JSAPI 接口
JSAPI 接口使用前,请在后台设置支付目录
JSAPI 接口请求步骤:
- 参照《获取 OPENID》章节,获得 OPENID
- 通过该 api 构造订单参数获取 jsapi 支付参数
- 通过 jssdk 或 WeixinJsBridge 方式自行发起支付
- 服务端接收异步通知
请求地址:https://payjs.cn/api/jsapi
请求参数:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
mchid | string(16) | Y | 商户号 |
total_fee | int(16) | Y | 金额。单位:分 |
out_trade_no | string(32) | Y | 用户端自主生成的订单号,在用户端要保证唯一性 |
body | string(64) | N | 订单标题 |
attach | string(127) | N | 用户自定义数据,在notify的时候会原样返回 |
notify_url | string(255) | N | 接收微信支付异步通知的回调地址。必须为可直接访问的URL,不能带参数、session验证、csrf验证。留空则不通知 |
callback_url | string(255) | N | 用户支付成功后,前端跳转地址 |
openid | string(32) | Y | 用户openid |
sign | string(32) | Y | 数据签名 详见签名算法 |
请求返回:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
return_code | int | Y | 0:失败 1:成功 |
return_msg | string(32) | Y | 失败原因 |
payjs_order_id | string(32) | Y | PAYJS 侧订单号 |
jsapi | string(255) | N | 用于发起支付的支付参数 |
sign | string(32) | Y | 数据签名 |
JSAPI 请求 DEMO:
<?php
// 引入 payjs.class.php
// 项目地址:https://github.com/payjs-cn/phpsdk
include("payjs.class.php");
$mchid = '123456';
$key = 'xxxxxx';
$data = [
'body' => 'test', // 订单标题
'out_trade_no' => time(), // 订单号
'total_fee' => 120, // 金额,单位:分
'openid' => 'xxxxxxxxxxx', // 通过openid接口获取到的openid
];
$payjs = new Payjs($mchid, $key);
$result = $payjs->jsapi($data);
print_r($result);
php
<?php
// 引入 payjs.class.php
// 项目地址:https://github.com/payjs-cn/phpsdk
include("payjs.class.php");
$mchid = '123456';
$key = 'xxxxxx';
$data = [
'body' => 'test', // 订单标题
'out_trade_no' => time(), // 订单号
'total_fee' => 120, // 金额,单位:分
'openid' => 'xxxxxxxxxxx', // 通过openid接口获取到的openid
];
$payjs = new Payjs($mchid, $key);
$result = $payjs->jsapi($data);
print_r($result);
python
# !/usr/bin/env Python3
# -*- coding: utf-8 -*-
import requests
import time
import hashlib
from urllib.parse import urlencode,unquote
'''
JSAPI 支付
'''
key = '' # 填写通信密钥
mchid = '' # 特写商户号
time = str(int(time.time()))
order = {
'body' : 'test', # 订单标题
'out_trade_no' : time, # 订单号
'total_fee' : 120, # 金额,单位:分
'openid' : 'xxxxxxxxxxx' # 通过openid接口获取到的openid
}
# 构造签名函数
def sign(attributes):
attributes_new = {k: attributes[k] for k in sorted(attributes.keys())}
return hashlib.md5((unquote(urlencode(attributes_new))+'&key='+key)
.encode(encoding='utf-8')).hexdigest().upper()
order['sign'] = sign(order)
request_url = "https://payjs.cn/api/jsapi"
# 返回结果中包含`jsapi`字段,该字段的值即是前端发起时所需的6个支付参数
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=order,headers=headers)
if response:
print(response.json())
go
package main
import (
"fmt"
"strings"
"net/http"
"net/url"
"io/ioutil"
)
func main(){
data := url.Values{"mchid":{"XXX"}, "total_fee":{"1"}, "out_trade_no":{"123123"},
"openid":{"XXX"}, "sign":{"XXX"}}
data2 := strings.NewReader(data.Encode())
resp, err := http.Post("https://payjs.cn/api/jsapi", "application/x-www-form-urlencoded", data2)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
// handle error
}
fmt.Println(string(body))
}
node
// 项目地址:https://github.com/payjs-cn/demo-nodejs
// 首先引入文件,并在config.js中配置商户号和通信密钥
var cfg = require("./config.js");
var pay = require("./pay.js");
var params = {
'total_fee': 1, //金额。单位:分
'out_trade_no': '123456789', //用户端自主生成的订单号
'body': '订单标题', //订单标题
'notify_url': '', //接收微信支付异步通知的回调地址。必须为可直接访问的URL,不能带参数、session验证、csrf验证。留空则不通知
'openid': '', // 通过openapi接口获取到的openid
};
pay.jsapi(params,function (msg) {
console.log(msg);
/**TODO 这里处理业务逻辑 */
});
java
// 完整代码:https://github.com/payjs-cn/demo-java
public Object Jsapi() {
Map<String,String> payData = new HashMap<>();
payData.put("mchid", PayjsConfig.mchid);
payData.put("total_fee", "100");
payData.put("out_trade_no", "83432749"); // 订单号 随便输的,自己生成一下就好了
payData.put("openid", "xxxxxxxxxxxxxx"); // 根据openid接口获取到的openid
payData.put("body","订单标题");
payData.put("attach","自定义数据");
payData.put("notify_url", "https://你的域名/api/pay/notify");
// 进行sign签名
payData.put("sign", sign(payData, PayjsConfig.key));
// 请求payjs
String result = HttpsUtils.sendPost(PayjsConfig.jsapiUrl, JSON.toJSONString(payData),null);
// 接口返回数据
return JSON.parseObject(result);
}
csharp
// 完整项目地址:https://github.com/payjs-cn/sdk-csharp
Payjs pay = new Payjs("YOUR MCHID", "YOUR KEY");
Dictionary<string, string> param = new Dictionary<string, string>();
param["total_fee"] = "1";
param["out_trade_no"] = DateTime.Now.Ticks.ToString();
param["body"] = "test";
param["attch"] = "user id";
param["notify_url"] = "YOUR notify_url";
param["openid"] = "user's openid";//获取用户openid:https://help.payjs.cn/api-lie-biao/huo-qu-openid.html
//返回原始json字符串
string jsonString = pay.jsapi(param);
前端发起支付演示代码:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<meta name="format-detection" content="email=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<link href="https://cdn.bootcss.com/weui/1.1.2/style/weui.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/zepto/1.2.0/zepto.min.js"></script>
</head>
<body style="padding:20px;">
<a href="javascript:;" class="weui-btn weui-btn_primary" id="payBtn">微信支付</a>
</body>
<script>
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}
function onBridgeReady() {
WeixinJSBridge.call('hideOptionMenu');
}
$('#payBtn').on('click', function () {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
// 以下6个支付参数通过payjs的jsapi接口获取
// **************************
"appId": "wxc5205a653b0259ac",
"timeStamp": "15100000000",
"nonceStr": "9cJEu27X6KehHGM8",
"package": "prepay_id=wx162234040923141245861167",
"signType": "MD5",
"paySign": "D64EF3ADBCA224E435D321619710C008"
// **************************
},
function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
WeixinJSBridge.call('closeWindow');
}
}
);
});
</script>