Разработка функционала WeChat Pay для публичного аккаунта: создание и тестирование
В последние дни мы использовали Node и H5-страницы для вызова функции оплаты через WeChat, чтобы удовлетворить потребности в оплате. Теперь мы хотим ещё раз пройтись по процессу разработки, чтобы помочь другим разработчикам успешно реализовать функционал оплаты через WeChat. (На данный момент WeChat не предоставляет функцию оплаты через Node).
1. Запрос кода (CODE)
Цель запроса кода — получить уникальный идентификатор пользователя openid и access_token. Используется следующий API:
Этот API требует следующих параметров:
2. Получение access_token и openid через код (CODE)
После получения значения кода можно использовать его для получения значений access_token и openid. Для этого используется следующий API:
Здесь используются следующие параметры:
3. Использование access_token для вызова API
Access_token можно использовать для последующих функций. Можно обратиться к официальным примерам.
4. Вызов функции оплаты в веб-браузере
Для вызова функции оплаты в браузере используется интерфейс WeixinJSBridge. Данные передаются в формате JSON. Обратите внимание, что объект WeixinJSBridge не работает в других браузерах.
Пример кода:
function onBridgeReady(){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId" : "wx2421b1c4370ec43b", //公众号名称,由商户传入
"timeStamp":" 1395712654", //时间戳,自1970年以来的秒数
"nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串
"package" : "prepay_id=u802345jgfjsdfgsdg888",
"signType" : "MD5", //微信签名方式:
"paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ) {} // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。
}
);
}
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}else{
onBridgeReady();
}
Обратите внимание на параметры, передаваемые в запросе:
Важно отметить, что параметр package является ключевым. Его необходимо получить из другого источника.
5. Получение package из интерфейса унифицированного заказа
Официальный API для получения prepay_id: [https://api.mch.weixin.qq.com/pay/unifiedorder][3]
Запрос содержит множество параметров, но некоторые из них не являются обязательными. Обязательные параметры включают:
{
appid : APPID,
attach : ATTACH,
body : BODY,
mch_id : MCH_ID,
nonce_str: NONCE_STR,
notify_url : NOTIFY_URL,// 微信付款后的回调地址
openid : OPENID,
out_trade_no : OUT_TRADE_NO ,//new Date().getTime(), //订单号
spbill_create_ip : SPBILL_CREATE_IP , //客户端的 ip
total_fee : TOTAL_FEE, //商品的价格, 此处需要注意的是这个价格是以分算的, 那么一般是元, 你需要转换为 **RMB 的元**
trade_type: 'JSAPI',
Требования к оформлению унифицированного заказа через WeChat
Унифицированный заказ через WeChat требует передачи данных в формате XML. Данные также должны быть подписаны. Сначала необходимо подписать данные. Правила подписи можно найти в документации WeChat (правила подписи методом один будут приведены ниже).
Правила подписи от WeChat:
После создания подписи данные необходимо оформить в виде XML-формата:
var body = ' ' + ''+config.wxappid+' ' + ''+obj.attach+' ' + ''+obj.body+' ' + '<mch_id>'+config.mch_id+'</mch_id> ' + '<nonce_str>'+obj.nonce_str+'</nonce_str> ' + '<notify_url>'+obj.notify_url+'</notify_url>' + ''+obj.openid+' ' + '<out_trade_no>'+obj.out_trade_no+'</out_trade_no>'+ '<spbill_create_ip>'+obj.spbill_create_ip+'</spbill_create_ip> ' + '<total_fee>'+obj.total_fee+'</total_fee> ' + '<trade_type>'+obj.trade_type+'</trade_type> ' + ''+obj.sign+' ' + // 此处必带签名, 否者微信在验证数据的时候是不通过的 '';
Далее необходимо запросить API для получения значения prepay_id. После успешной проверки данных WeChat вернёт нужное значение.
API: https://api.mch.weixin.qq.com/pay/unifiedorder.
Получение prepay_id и возможность прямого вызова функции оплаты через H5
Если получен prepay_id, то параметры для вызова функции оплаты через H5 будут выглядеть следующим образом:
{ "appId": "wx2421b1c4370ec43b", //公众号名称,由商户传入 "timeStamp": "1395712654", //时间戳,自1970年以来的秒数 "nonceStr": "e61463f8efa94090b1f366cccfbbb444", //随机串 "package": "prepay_id=u802345jgfjsdfgsdg888", "signType": "MD5", //微信签名方式: }
Все параметры, участвующие в вызове, должны быть подписаны по тем же правилам, что и выше. После создания подписи её нужно присвоить параметру paySign в запросе на оплату через H5.
Окончательный запрос будет выглядеть так:
{ "appId": "wx2421b1c4370ec43b", //公众号名称,由商户传入 "timeStamp": "1395712654", //时间戳,自1970年以来的秒数 "nonceStr": "e61463f8efa94090b1f366cccfbbb444", //随机串 "package": "prepay_id=u802345jgfjsdfgsdg888", "signType": "MD5", //微信签名方式: "paySign": "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 }
При отсутствии проблем на всех этапах вызов функции оплаты через H5 будет работать аналогично оригинальному функционалу.
Завершение оплаты и обратный вызов
После успешной оплаты WeChat отправит информацию о результате в функцию обратного вызова на странице H5. Если res.err_msg == «get_brand_wcpay_request: ok», то оплата прошла успешно. Однако это не означает завершение процесса. Необходимо сохранить информацию об оплате в базе данных.
Также необходимо помнить о параметре notify_url в запросе на оформление унифицированного заказа. Этот адрес будет передан WeChat после оплаты. WeChat отправит запрос на этот адрес с информацией о платеже в формате XML:
... ...Необходимо проанализировать эти данные в соответствии с бизнес-логикой.
Важно отметить, что WeChat ожидает ответа от вашего приложения после получения данных. Если ответ не будет отправлен, WeChat продолжит отправлять запросы. Поэтому необходимо предоставить ответ в формате XML, например:
. **Небольшая проблема: разработка с использованием node и express**Если в обратном вызове после успешной оплаты через WeChat вы не получаете значения XML, вам необходимо установить компонент body-parser-xml. Вы можете установить его с помощью команды npm install body-parser-xml --save
. В файле app.js используйте промежуточное ПО:
// Решение для данных обратного вызова уведомлений о платеже через WeChat
app.use(bodyParser.xml({
limit: '2MB', // Отклонять полезные данные больше 1 МБ
xmlParseOptions: {
normalize: true, // Обрезать пробелы внутри текстовых узлов
normalizeTags: true, // Преобразовывать теги в нижний регистр
explicitArray: false // Помещать узлы в массив только если их больше одного
}
}));
После этого вы сможете нормально получать данные XML от WeChat.
`pay.getAccessToken({
notify_url : 'http://demo.com/', //URL обратного вызова после завершения платежа через WeChat
out_trade_no : new Date().getTime(), //Номер заказа
attach : 'Наименование',
body : 'Информация о покупке',
total_fee : '1', // Сумма здесь в единицах
spbill_create_ip : req.connection.remoteAddress,
}, function (error, responseData) {
res.render('payment', {
title : 'Платёж через WeChat',
wxPayParams : JSON.stringify(responseData),
//userInfo : userInfo
});
});`
На этом всё, думаю, что это почти всё. Пожалуйста, поправьте меня, если я что-то упустил.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )