微信支付,JSAPI支付,APP支付,H5支付,Native支付,小程序支付功能详情以及回调处理

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

一.支付相关文档地址

支付wiki https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml
支付api: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/index.shtml
开发工具包(SDK)下载 https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml#part-1

二.JSAPI支付

1.产品介绍

1.1简介

JSAPI支付是指商户通过调用微信支付提供的JSAPI接口在支付场景中调起微信支付模块完成收款。

1.2 应用场景

JSAPI支付适用于线下场所、公众号场景和PC网站场景。
商户已有H5商城网站用户通过消息或扫描二维码在微信内打开网页时可以调用微信支付完成下单购买的流程。具体操作流程如下

步骤一 如图2.1商户下发图文消息或者通过自定义菜单吸引用户点击进入商户网页。

步骤二 如图2.2进入商户网页用户选择购买完成选购流程。

步骤三 如图2.3调起微信支付控件用户开始输入支付密码。

图2.1 商户网页下单

图2.2 请求微信支付

图2.3 用户确认支付输入密码

步骤四 如图2.4密码验证通过支付成功。商户后台得到支付成功的通知。

步骤五 如图2.5返回商户页面显示购买成功。该页面由商户自定义。

步骤六 如图2.6微信支付公众号下发支付凭证。

图2.4 用户支付成功提示

图2.5 返回商户页面

图2.6 用户收到微信通知

2.接入前准备

2.1.选择接入模式

商户/服务商在接入前首先要判断自己公司注册区域适用的接入模式微信支付目前提供两种接入方式直连模式服务商模式

● 直连模式

信息、资金流微信支付—>直连商户

直连模式商户自行申请入驻微信支付无需服务商协助。商户平台申请成为直连商户

● 服务商模式

—— 信息流 —— 资金流

服务商模式商户申请成为微信支付服务商服务商自身无法作为一个直连商户直接发起交易其发起交易必须传入相关特约商户商户号的参数信息。 服务商平台 申请成为服务商
请结合自身实际情况来选择接入模式。
服务商模式相关说明详见 服务商模式 介绍

2.2 参数申请

商户自行申请入驻微信支付无服务商协助。 商户平台 申请成为直连商户

2.2.1申请APPID

由于微信支付的产品体系全部搭载于微信的社交体系之上所以直连商户或服务商接入微信支付之前都需要有一个微信社交载体该载体对应的ID即为APPID。
对于直连商户该社交载体可以是公众号 什么是公众号 小程序 什么是小程序 或APP。
如申请社交载体为公众号请前往 公众平台 申请
如申请社交载体为小程序请前往 小程序平台 申请
如商户已拥有自己的APP且希望该APP接入微信支付请前往 开放平台 申请
商户可根据实际的业务需求来选择申请不同的社交载体。
各类社交载体一旦申请成功后可以登录对应平台查看账号信息以获取对应的appid。

2.2.2申请mchid

申请mchid和APPID的操作互不影响可以并行操作申请地址如下 商户号申请平台

申请成功后会向服务商填写的联系邮箱下发通知邮件内容包含申请成功的mchid及其登录账号密码请妥善保存。

注意一个mchid只能对应一个结算币种若需要使用多个币种收款需要申请对应数量的mchid。

2.2.3绑定APPID及mchid

APPID和mchid全部申请完毕后需要建立两者之间的绑定关系。

直连模式下APPID与mchid之间的关系为多对多即一个APPID下可以绑定多个mchid而一个mchid也可以绑定多个APPID。

3.配置API key

API v3密钥主要用于平台证书解密、回调信息解密具体使用方式可参见接口规则文档中 证书和回调报文解密 章节。

请根据以下步骤配置API key

3.1登录微信商户平台进入【账户中心 > API安全 】目录设置APIV3密钥。

3.2在弹出窗口中点击“已沟通”

3.3 输入API密钥内容为32位字符包括数字及大小写字母。点击获取短信验证码

3.4 输入短信验证码点击“确认”即设置成功

4.下载并配置商户证书

商户API证书具体使用说明可参见接口规则文档中私钥和证书章节

商户可登录微信商户平台在【账户中心】->【API安全】目录下载证书

以下为具体下载步骤

4.1从2018年底开始微信支付新入驻机构及商户都将使用CA签发证书在证书申请页面上点击“申请证书”

4.2在弹出窗口中点击“确定”

4.3在弹出窗口内点击“下载证书工具”按钮下载证书工具

4.4安装证书工具并打开选择证书需要存储的路径后点击“申请证书”

4.5在证书工具中将复制的商户信息粘贴并点击“下一步”

4.6获取请求串

4.7生成证书串

步骤1 在【商户平台】-“复制证书串”环节点击“复制证书串”按钮后

步骤2 在【证书工具】-“复制请求串”环节点击“下一步”按钮进入“粘贴证书串”环节

步骤3 在【证书工具】-“粘贴证书串”环节点击“粘贴”按钮后

步骤4 点击“下一步”按钮进入【证书工具】-“生成证书”环节

4.8在【证书工具】-“生成证书”环节已完成申请证书流程点击“查看证书文件夹”查看已生成的证书文件

5.配置应用

设置支付授权目录

支付授权目录说明

1)商户最后请求拉起微信支付收银台的页面地址我们称之为“支付授权目录”例如https://www.weixin.com/pay.php的支付授权目录为https://www.weixin.com/

2)商户实际的支付授权目录必须和在微信支付商户平台设置的一致否则会报错“当前页面的URL未注册”

支付授权目录设置说明

登录【微信支付商户平台—>产品中心—>开发配置】设置后一般5分钟内生效。

支付授权目录校验规则说明

1)如果支付授权目录设置为顶级域名例如https://www.weixin.com/ 那么只校验顶级域名不校验后缀

2)如果支付授权目录设置为多级目录就会进行全匹配例如设置支付授权目录为https://www.weixin.com/abc/123/则实际请求页面目录不能为https://www.weixin.com/abc/也不能为https://www.weixin.com/abc/123/pay/必须为https://www.weixin.com/abc/123/

设置授权域名

开发JSAPI支付时在JSAPI下单接口中要求必传用户openid而获取openid则需要您在微信公众平台设置获取openid的域名只有被设置过的域名才是一个有效的获取openid的域名否则将获取失败。具体界面如图所示

开通流程在入驻时选择线下场所公众号场景PC网站场景的商户系统默认开通此功能其他商户如有需要可以在入驻后前往商户平台-产品中心-JSAPI支付-申请开通

3.开发指引

3.1. 接口规则

为了在保证支付安全的前提下带给商户简单、一致且易用的开发体验我们推出了全新的微信支付APIv3接口。该版本API的具体规则请参考“ APIv3接口规则
备注当前接口用于微信国内钱包

3.2. 开发准备

3.2.1. 搭建和配置开发环境

为了帮助开发者调用开放接口我们提供了JAVA、PHP、GO三种语言版本的开发库封装了签名生成、签名验证、敏感信息加/解密、媒体文件上传等基础功能更多语言版本的开发库将在近期陆续提供

测试步骤

1、根据自身开发语言选择对应的开发库并构建项目具体配置请参考下面链接的详细说明

wechatpay-java推荐wechatpay-apache-httpclient适用于Java开发者。

wechatpay-php推荐、wechatpay-guzzle-middleware适用于PHP开发者

注当前开发指引接口PHP示例代码采用wechatpay-guzzle-middleware版本

wechatpay-go适用于Go开发者

更多资源可前往微信支付开发者社区搜索查看

2、创建加载商户私钥、加载平台证书、初始化httpClient的通用方法

use GuzzleHttp\Exception\RequestException;
use WechatPay\GuzzleMiddleware\WechatPayMiddleware;
use WechatPay\GuzzleMiddleware\Util\PemUtil;
use GuzzleHttp\HandlerStack;
 
// 商户相关配置
$merchantId = '1000100'; // 商户号
$merchantSerialNumber = 'XXXXXXXXXX'; // 商户API证书序列号
$merchantPrivateKey = PemUtil::loadPrivateKey('./path/to/mch/private/key.pem'); // 商户私钥文件路径
 
// 微信支付平台配置
$wechatpayCertificate = PemUtil::loadCertificate('./path/to/wechatpay/cert.pem'); // 微信支付平台证书文件路径
 
// 构造一个WechatPayMiddleware
$wechatpayMiddleware = WechatPayMiddleware::builder()
    ->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 传入商户相关配置
    ->withWechatPay([ $wechatpayCertificate ]) // 可传入多个微信支付平台证书参数类型为array
    ->build();
 
// 将WechatPayMiddleware添加到Guzzle的HandlerStack中
$stack = GuzzleHttp\HandlerStack::create();
$stack->push($wechatpayMiddleware, 'wechatpay');
 
// 创建Guzzle HTTP Client时将HandlerStack传入接下来正常使用Guzzle发起API请求WechatPayMiddleware会自动地处理签名和验签
$client = new GuzzleHttp\Client(['handler' => $stack]);

3、基于接口的示例代码替换请求参数后可发起测试

说明

• 上面的开发库为微信支付官方开发库其它没有审核或者控制下的第三方工具和库微信支付不保证它们的安全性和可靠性

通过包管理工具引入SDK后可根据下面每个接口的示例代码替换相关参数后进行快速测试

开发者如果想详细了解签名生成、签名验证、敏感信息加/解密、媒体文件上传等常用方法的具体代码实现可阅读下面的详细说明

1.签名生成

2.签名验证

3.敏感信息加解密

4.merchantPrivateKey私钥

5.wechatpayCertificates平台证书

6.APIV3KeyV3 key

如想更详细的了解我们的接口规则可查看我们的接口规则指引文档

3.2.2. 业务开发配置

3.2.2.1. 设置支付目录

支付授权目录说明

a、商户最后请求拉起微信支付收银台的页面地址我们称之为“支付目录”例如https://www.weixin.com/pay.php

b、商户实际的支付目录必须和在微信支付商户平台设置的一致否则会报错“当前页面的URL未注册”

支付授权目录设置说明

登录微信支付【商户平台->产品中心->开发配置】设置后一般5分钟内生效。

图1支付目录配置

支付授权目录校验规则说明

a、如果支付授权目录设置为顶级域名例如https://www.weixin.com/ 那么只校验顶级域名不校验后缀

b、如果支付授权目录设置为多级目录就会进行全匹配例如设置支付授权目录为https://www.weixin.com/abc/123/则实际请求页面目录不能为https://www.weixin.com/abc/也不能为https://www.weixin.com/abc/123/pay/必须为https://www.weixin.com/abc/123/

3.2.2.2. 设置授权域名

授权域名说明开发JSAPI支付时在JSAPI下单接口中要求必传用户openid而获取openid则需要您在公众平台设置获取openid的域名只有被设置过的域名才是一个有效的获取openid的域名否则将获取失败。具体配置页如图2所示

授权域名设置说明登录【微信公众平台->公众号设置->功能设置】

3.3. 快速接入

3.3.1. 业务流程图

重点步骤说明

步骤3 用户下单发起支付商户可通过JSAPI下单创建支付订单。

步骤8 商户可在微信浏览器内通过JSAPI调起支付API调起微信支付发起支付请求。

步骤15 用户支付成功后商户可接收到微信支付支付结果通知支付结果通知API

步骤20 商户在没有接收到微信支付结果通知的情况下需要主动调用查询订单API查询支付结果。

3.3.2. API接入

文档展示了如何使用微信支付服务端 SDK 快速接入JSAPI支付产品完成与微信支付对接的部分。

注意

  • 文档中的代码示例是用来阐述 API 基本使用方法代码中的示例参数需替换成商户自己账号及请求参数才能跑通

  • 以下接入步骤仅提供参考请商户结合自身业务需求进行评估、修改。

3.3.2.1. 【服务端】JSAPI下单
步骤说明用户通过商户下发的模板消息或扫描二维码在微信内进入商户网页当用户选择相关商户购买时商户系统先调用该接口在微信支付服务后台生成预支付交易单。
try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi', //请求URL
        [
            // JSON请求体
            'json' => [
                "time_expire" => "2018-06-08T10:34:56+08:00",
                "amount" => [
                    "total" => 100,
                    "currency" => "CNY",
                ],
                "mchid" => "1230000109",
                "description" => "Image形象店-深圳腾大-QQ公仔",
                "notify_url" => "https://www.weixin.qq.com/wxpay/pay.php",
                "payer" => [
                    "openid" => "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o",
                ],
                "out_trade_no" => "1217752501201407033233368018",
                "goods_tag" => "WXG",
                "appid" => "wxd678efh567hg6787",
                "attach" => "自定义数据说明",
                "detail" => [
                    "invoice_id" => "wx123",
                    "goods_detail" => [
                        [
                            "goods_name" => "iPhoneX 256G",
                            "wechatpay_goods_id" => "1001",
                            "quantity" => 1,
                            "merchant_goods_id" => "商品编码",
                            "unit_price" => 828800,
                        ],
                        [
                            "goods_name" => "iPhoneX 256G",
                            "wechatpay_goods_id" => "1001",
                            "quantity" => 1,
                            "merchant_goods_id" => "商品编码",
                            "unit_price" => 828800,
                        ],
                    ],
                    "cost_price" => 608800,
                ],
                "scene_info" => [
                    "store_info" => [
                        "address" => "广东省深圳市南山区科技中一道10000号",
                        "area_code" => "440305",
                        "name" => "腾讯大厦分店",
                        "id" => "0001",
                    ],
                    "device_id" => "013467007045764",
                    "payer_client_ip" => "14.23.150.211",
                ]
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功无返回Body
        echo "success";
    }
    } catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
    }
    

重要入参说明

out_trade_no商户系统内部订单号只能是数字、大小写字母_-*且在同一个商户号下唯一

description商品描述

notify_url支付回调通知URL该地址必须为直接可访问的URL不允许携带查询串

total订单总金额单位为分

openidopenid是微信用户在appid下的唯一用户标识appid不同则获取到的openid就不同可用于永久标记一个用户。openid获取方式请参考以下文档小程序获取openid公众号获取openidAPP获取openid

更多参数、响应详情及错误码请参见JSAPI下单接口文档

3.2.2.【客户端】JSAPI调起支付
步骤说明通过JSAPI下单API成功获取预支付交易会话标识prepay_id后需要通过JSAPI调起支付API来调起微信支付收银台

注意

• WeixinJSBridge内置对象在其他浏览器中无效

• 此API需要将请求参数进行签名参与签名的参数为appId、timeStamp、nonceStr、package参数区分大小写

示例代码

function onBridgeReady(){
      WeixinJSBridge.invoke('getBrandWCPayRequest', {
          "appId": "wx2421b1c4370ecxxx",   //公众号ID由商户传入    "timeStamp": "1395712654",   //时间戳自1970年以来的秒数    "nonceStr": "e61463f8efa94090b1f366cccfbbb444",      //随机串    "package": "prepay_id=wx21201855730335ac86f8c43d1889123400",
          "signType": "RSA",     //微信签名方式    "paySign": "oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ\/X+QBhcCYL21N7cHCTUxbQ+EAt6Uy+lwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuT+Cdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZV+JSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8Fu+LozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2+AehHvz+n64GDmXxbX++IOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq\/xDg=="//微信签名
      },
      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);
      } elseif (document.attachEvent) {
          document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
          document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
      }
  } else {
      onBridgeReady();
  }	  
  

重要入参说明

packageJSAPI下单接口返回的prepay_id参数值提交格式如prepay_id=***

signType该接口V3版本仅支持RSA

paySign签名

paySign生成规则、响应详情及错误码请参见 JSAPI调起支付接口文档

3.2.3.【服务端】接收支付结果通知

步骤说明当用户完成支付微信会把相关支付结果将通过异步回调的方式通知商户商户需要接收处理并按文档规范返回应答

注意

  • 支付结果通知是以POST 方法访问商户设置的通知url通知的数据以JSON 格式通过请求主体BODY传输。通知的数据包括了加密的支付结果详情

  • 加密不能保证通知请求来自微信。微信会对发送给商户的通知进行签名并将签名值放在通知的HTTP头Wechatpay-Signature。商户应当验证签名以确认请求来自微信而不是其他的第三方。签名验证的算法请参考 《微信支付API v3签名验证》

  • 支付通知http应答码为200或204才会当作正常接收当回调处理异常时应答的HTTP状态码应为500或者4xx

  • 商户成功接收到回调通知后应返回成功的http应答码为200或204

  • 同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是当商户系统收到通知进行处理时先检查对应业务数据的状态并判断该通知是否已经处理。如果未处理则再进行处理如果已处理则直接返回结果成功。在对业务数据进行状态检查和处理之前要采用数据锁进行并发控制以避免函数重入造成的数据混乱

  • 对后台通知交互时如果微信收到商户的应答不符合规范或超时微信认为通知失败微信会通过一定的策略定期重新发起通知尽可能提高通知的成功率但微信不保证通知最终能成功。通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序支付通知API接口文档

3.2.4. 【服务端】查询订单

步骤说明当商户后台、网络、服务器等出现异常商户系统最终未接收到支付通知时商户可通过查询订单接口核实订单支付状态

示例代码(通过微信订单号查询)

ry {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/pay/transactions/id/1217752501201407033233368018?mchid=1230000109', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}

注意

  • 查询订单可通过微信支付订单号商户订单号两种方式查询两种查询方式返回结果相同

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序查询订单API接口文档

3.2.5. 【服务端】关闭订单

步骤说明当商户订单支付失败需要生成新单号重新发起支付要对原订单号调用关单避免重复支付系统下单后用户支付超时系统退出不再受理避免用户继续请调用关单接口

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no}/close', //请求URL
        [
            // JSON请求体
            'json' => [
                "mchid " => "1230000109",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功无返回Body
        echo "success";
    }
  } catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
  }
  

3.4. 常见问题

Q获取OPENID接口报“此公众号并没有这些scope的权限错误码10005”如下图所示

A请按以下步骤进行排查

1. 建议检查一下公众号的功能。比如是不是在订阅号/未认证的公众号里面尝试调用认证服务号的功能

2. 确认APPID是否认证过期或者APPID填写错误

3. 请尝试使用snsapi_userinfo的授权登录方式

QJSAPI调起支付接口报“商家暂时没有此类交易权限请联系商家客服”

A请按以下步骤进行排查

1. 请检查你的下单接口是否指定了支付用户的身份该功能需单独开通指定身份支付权限方可使用

2. 请确认你使用的商户号是否有jsapi支付的权限可登录商户平台-产品中心查看

QJSAPI调起支付接口报“当前页面的URL未注册”

A请检查下单接口中使用的商户号是否在商户平台配置了对应的支付目录可参考“设置支付目录”章节说明

Q获取OPENID接口报“redirect_url域名与后台配置不一致错误码10003”

A请按以下步骤进行排查

1. 检查下单接口传的appid与获取openid接口的appid是否同一个需一致

2. 检查appid对应的公众号后台是否配置的授权域名和获取openid的域名一致。授权域名配置路径【公众平台-> 设置-> 公众号设置-> 功能设置–> 网页授权域名】

QJSAPI调起支付接口报“该商户暂不支持通过外部拉起微信完成支付”

AJSAPI支付只能从微信浏览器内发起支付请求

4.支付API列表

模块名称

功能列表

描述

JSAPI支付

JSAPI下单

通过本接口提交微信支付JSAPI支付订单。

查询订单

通过此接口查询订单状态。

关闭订单

通过此接口关闭待支付订单。

JSAPI调起支付

通过使用微信浏览器里面H5网页中调用微信JSSDK执行JS调起支付。

支付结果通知

微信支付通过支付通知接口将用户支付成功消息通知给商户。

申请退款

商户可以通过该接口将支付金额退还给买家。

查询单笔退款

提交退款申请后通过调用该接口查询退款状态。

退款结果通知

微信支付通过退款通知接口将用户退款成功消息通知给商户。

申请交易账单

商户可以通过该接口获取交易账单文件的下载地址。

申请资金账单

商户可以通过该接口获取资金账单文件的下载地址。

下载账单

通过申请交易/资金账单获取到download_url在该接口获取到对应的账单。

三.APP支付

  1. 产品介绍

1.1简介

APP支付是指商户通过在移动端应用APP中集成开放SDK调起微信支付模块来完成支付。目前微信支付支持手机系统有IOS苹果、Android安卓和WPWindows Phone

1.2应用场景

APP支付适用于在移动端APP中集成微信支付功能的场景。商户APP调用微信提供的SDK调用微信支付模块商户APP会跳转到微信中完成支付支付完后跳回到商户APP内最后展示支付结果。具体操作流程如下

步骤一 用户进入商户APP选择商品下单、确认购买进入支付环节。商户服务后台生成支付订单签名后将数据传输到APP端。以微信提供的DEMO为例见图1.1。

步骤二 用户点击后发起支付操作进入到微信界面调起微信支付出现确认支付界面见图1.2。

步骤三 用户确认收款方和金额点击立即支付后出现输入密码界面可选择零钱或银行卡支付见图1.3。

图1.1 商户APP界面实例

图1.2 跳转到微信支付

图1.3 用户确认支付

步骤四 输入正确密码后支付完成用户端微信出现支付详情页面。见图1.4。

步骤五 回跳到商户APP中商户APP根据支付结果个性化展示订单处理结果。见图1.5。

图1.4 支付成功提示页面

图1.5 返回到商户APP提示

  1. 接入前准备

2.1.选择接入模式

商户/服务商在接入前首先要判断自己公司注册区域适用的接入模式微信支付目前提供两种接入方式直连模式和服务商模式。

● 直连模式

信息、资金流微信支付—>直连商户

直连模式商户自行申请入驻微信支付无需服务商协助。商户平台申请成为直连商户

● 服务商模式

服务商模式商户申请成为微信支付服务商服务商自身无法作为一个直连商户直接发起交易其发起交易必须传入相关特约商户商户号的参数信息。服务商平台申请成为服务商

请结合自身实际情况来选择接入模式。

服务商模式相关说明详见服务商模式介绍

2.2.参数申请

商户自行申请入驻微信支付无服务商协助。商户平台申请成为直连商户

2.2.1申请APPID

由于微信支付的产品体系全部搭载于微信的社交体系之上所以直连商户或服务商接入微信支付之前都需要有一个微信社交载体该载体对应的ID即为APPID。

对于直连商户该社交载体可以是公众号什么是公众号小程序什么是小程序或APP。

如申请社交载体为公众号请前往 公众平台申请

如申请社交载体为小程序请前往 小程序平台 申请

如商户已拥有自己的APP且希望该APP接入微信支付请前往 开放平台申请

商户可根据实际的业务需求来选择申请不同的社交载体。

各类社交载体一旦申请成功后可以登录对应平台查看账号信息以获取对应的appid。

2.2.2申请mchid

申请mchid和APPID的操作互不影响可以并行操作申请地址如下 商户号申请平台

申请成功后会向服务商填写的联系邮箱下发通知邮件内容包含申请成功的mchid及其登录账号密码请妥善保存。

注意一个mchid只能对应一个结算币种若需要使用多个币种收款需要申请对应数量的mchid。

2.2.3绑定APPID及mchid

APPID和mchid全部申请完毕后需要建立两者之间的绑定关系。

直连模式下APPID与mchid之间的关系为多对多即一个APPID下可以绑定多个mchid而一个mchid也可以绑定多个APPID。

2.3.配置API key

API v3密钥主要用于平台证书解密、回调信息解密具体使用方式可参见接口规则文档中证书和回调报文解密章节。

请根据以下步骤配置API key

2.3.1登录微信商户平台进入【账户中心 > API安全 】目录设置APIV3密钥

2.3.2在弹出窗口中点击“已沟通”

2.3.3输入API密钥内容为32位字符包括数字及大小写字母。点击获取短信验证码

2.3.4输入短信验证码点击“确认”即设置成功

2.4.下载并配置商户证书

商户API证书具体使用说明可参见接口规则文档中私钥和证书章节

商户可登录微信商户平台在【账户中心】->【API安全】目录下载证书

以下为具体下载步骤

2.4.1从2018年底开始微信支付新入驻机构及商户都将使用CA签发证书在证书申请页面上点击“申请证书”

2.4.2在弹出窗口中点击“确定”

2.4.3在弹出窗口内点击“下载证书工具”按钮下载证书工具

2.4.4安装证书工具并打开选择证书需要存储的路径后点击“申请证书”

2.4.5在证书工具中将复制的商户信息粘贴并点击“下一步”

2.4.6获取请求串

2.4.7生成证书串

步骤1 在【商户平台】-“复制证书串”环节点击“复制证书串”按钮后

步骤2 在【证书工具】-“复制请求串”环节点击“下一步”按钮进入“粘贴证书串”环节

步骤3 在【证书工具】-“粘贴证书串”环节点击“粘贴”按钮后

步骤4 点击“下一步”按钮进入【证书工具】-“生成证书”环节

2.4.8在【证书工具】-“生成证书”环节已完成申请证书流程点击“查看证书文件夹”查看已生成的证书文件

2.5.APP支付页面规范

APP商户截图规范

APP商户申请时如选择提供截图请参见《微信支付APP商户截图标准》提供APP首页截图、APP尾页截图、APP应用内截图和APP支付页截图。

APP收银台界面规范

列表首位+默认勾选+标准logo+推荐标签+标语

素材下载《微信支付logo、APP支付素材下载

开通流程在入驻时选择APP场景的商户系统默认开通此功能其他商户如有需要可以在入驻后前往商户平台-产品中心-APP支付-申请开通

  1. 开发指引

3.1. 接口规则

为了在保证支付安全的前提下带给商户简单、一致且易用的开发体验我们推出了全新的微信支付APIv3接口。该版本API的具体规则请参考“APIv3接口规则

备注当前接口用于微信国内钱包

3.2. 开发准备

3.2.1. 搭建和配置开发环境

为了帮助开发者调用开放接口我们提供了JAVA、PHP、GO三种语言版本的开发库封装了签名生成、签名验证、敏感信息加/解密、媒体文件上传等基础功能更多语言版本的开发库将在近期陆续提供

测试步骤

1、根据自身开发语言选择对应的开发库并构建项目具体配置请参考下面链接的详细说明

wechatpay-java推荐wechatpay-apache-httpclient适用于Java开发者。

wechatpay-php推荐、wechatpay-guzzle-middleware适用于PHP开发者

注当前开发指引接口PHP示例代码采用wechatpay-guzzle-middleware版本

wechatpay-go适用于Go开发者

更多资源可前往微信支付开发者社区搜索查看

2、创建加载商户私钥、加载平台证书、初始化httpClient的通用方法

use GuzzleHttp\Exception\RequestException;
use WechatPay\GuzzleMiddleware\WechatPayMiddleware;
use WechatPay\GuzzleMiddleware\Util\PemUtil;
use GuzzleHttp\HandlerStack;
 
// 商户相关配置
$merchantId = '1000100'; // 商户号
$merchantSerialNumber = 'XXXXXXXXXX'; // 商户API证书序列号
$merchantPrivateKey = PemUtil::loadPrivateKey('./path/to/mch/private/key.pem'); // 商户私钥文件路径
 
// 微信支付平台配置
$wechatpayCertificate = PemUtil::loadCertificate('./path/to/wechatpay/cert.pem'); // 微信支付平台证书文件路径
 
// 构造一个WechatPayMiddleware
$wechatpayMiddleware = WechatPayMiddleware::builder()
    ->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 传入商户相关配置
    ->withWechatPay([ $wechatpayCertificate ]) // 可传入多个微信支付平台证书参数类型为array
    ->build();
 
// 将WechatPayMiddleware添加到Guzzle的HandlerStack中
$stack = GuzzleHttp\HandlerStack::create();
$stack->push($wechatpayMiddleware, 'wechatpay');
 
// 创建Guzzle HTTP Client时将HandlerStack传入接下来正常使用Guzzle发起API请求WechatPayMiddleware会自动地处理签名和验签
$client = new GuzzleHttp\Client(['handler' => $stack]);

、基于接口的示例代码替换请求参数后可发起测试

说明

• 上面的开发库为微信支付官方开发库其它没有审核或者控制下的第三方工具和库微信支付不保证它们的安全性和可靠性

通过包管理工具引入SDK后可根据下面每个接口的示例代码替换相关参数后进行快速测试

开发者如果想详细了解签名生成、签名验证、敏感信息加/解密、媒体文件上传等常用方法的具体代码实现可阅读下面的详细说明

1.签名生成

2.签名验证

3.敏感信息加解密

4.merchantPrivateKey私钥

5.wechatpayCertificates平台证书

6.APIV3KeyV3 key

如想更详细的了解我们的接口规则可查看我们的接口规则指引文档

3.2.2. 业务开发配置

3.2.2.1. 注册APP

APP接入微信支付需要先将商户APP在微信开放平台进行注册登记APP开发参数以生成APPID。具体操作步骤如下

一、登录微信开放平台进入【管理中心 → 移动应用 → 创建移动应用】

二、完成基本信息的录入商户需要在本步骤提交APP对应的下载地址应用官网应用水印icon等业务信息

三、完成平台信息的录入商户需要在本步骤提交APP在Android及iOS端对应的开发参数包括Android端应用的包名应用签名iOS端应用的bundle ID, universal link等

注意

四、以上信息全部提交完成后即完成APP的注册商户可在【管理中心 → 移动应用】中选择具体的应用查看其APPID及已获得的接口能力

五、获取到APP的APPID后需要将该APPID与商户的收款mch_id进行绑定商户可登录商户平台后前往【产品中心 -> AppID账号管理】界面中进行AppID的绑定及管理界面如图所示

3.3. 快速接入

3.3.1. 业务流程图

重点步骤说明

步骤3用户下单发起支付商户可通过微信支付APP下单API创建支付订单。

商户调用APP下单API后分正常返回和异常返回情况

  • 正常返回返回prepay_id商户可根据返回的prepay_id来生成调用OpenSDK的签名以执行下一步。

步骤8 商户通过APP调起支付OpenSDK调起微信支付发起支付请求有关OpenSDK调起支付的详细说明请参考2.2.2部分的说明

步骤15-19: 用户支付成功后商户可通过以下两种方式获取订单状态

我们通过以下接口将用户确认订单信息回调通知给商户系统

方法一支付结果通知。用户支付成功后微信支付会将支付成功的结果以回调通知的形式同步给商户商户的回调地址需要在调用APP下单API时传入notify_url参数。

方法二当因网络抖动或本身notify_url存在问题等原因导致无法接收到回调通知时商户也可主动调用查询订单API 查询订单API来获取订单状态

3.3.2. API接入含示例代码

本文档展示了如何使用微信支付服务端 SDK 快速接入APP支付产品完成与微信支付对接的部分。

注意

  • 文档中的代码示例是用来阐述 API 基本使用方法代码中的示例参数需替换成商户自己账号及参数才能跑通。

  • 以下接入步骤仅提供参考请商户结合自身业务需求进行评估、修改。

3.3.2.1. 【服务端】APP下单

步骤说明用户在商户APP内完成商户选择后进入支付页面商户需要通过后端请求该APP下单API来获取预支付ID。

示例代码

try {
  $resp = $client->request(
      'POST',
      'https://api.mch.weixin.qq.com/v3/pay/transactions/app', //请求URL
      [
          // JSON请求体
          'json' => [
              "time_expire" => "2018-06-08T10:34:56+08:00", 
              "amount" => [
                  "total" => 100, 
                  "currency" => "CNY", 
              ],
              "mchid" => "1230000109", 
              "description" => "Image形象店-深圳腾大-QQ公仔", 
              "notify_url" => "https://www.weixin.qq.com/wxpay/pay.php", 
              "out_trade_no" => "1217752501201407033233368018", 
              "goods_tag" => "WXG", 
              "appid" => "wxd678efh567hg6787", 
              "attach" => "自定义数据说明", 
              "detail" => [
                  "invoice_id" => "wx123", 
                  "goods_detail" => [
                      [
                          "goods_name" => "iPhoneX 256G", 
                          "wechatpay_goods_id" => "1001", 
                          "quantity" => 1, 
                          "merchant_goods_id" => "商品编码", 
                          "unit_price" => 828800, 
                      ],
                      [
                          "goods_name" => "iPhoneX 256G", 
                          "wechatpay_goods_id" => "1001", 
                          "quantity" => 1, 
                          "merchant_goods_id" => "商品编码", 
                          "unit_price" => 828800, 
                      ],
                  ],
                  "cost_price" => 608800, 
              ],
              "scene_info" => [
                  "store_info" => [
                      "address" => "广东省深圳市南山区科技中一道10000号", 
                      "area_code" => "440305", 
                      "name" => "腾讯大厦分店", 
                      "id" => "0001", 
                  ],
                  "device_id" => "013467007045764", 
                  "payer_client_ip" => "14.23.150.211", 
              ]
          ],
          'headers' => [ 'Accept' => 'application/json' ]
      ]
  );
  $statusCode = $resp->getStatusCode();
  if ($statusCode == 200) { //处理成功
      echo "success,return body = " . $resp->getBody()->getContents()."\n";
  } else if ($statusCode == 204) { //处理成功无返回Body
      echo "success";
  }
} catch (RequestException $e) {
  // 进行错误处理
  echo $e->getMessage()."\n";
  if ($e->hasResponse()) {
      echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
  }
  return;

}

重要参数说明

• out_trade_no商户系统内部订单号只能是数字、大小写字母_-*且在同一个商户号下唯一

• description商品描述

• notify_url支付回调通知URL该地址必须为直接可访问的URL不允许携带查询串

• total订单总金额单位为分

更多参数、响应详情及错误码请参见APP下单API接口文档

3.3.2.2. 【客户端】OpenSDK调起支付

步骤说明通过APP下单API成功获取预支付交易会话标识prepay_id后需要通过OpenSDK来调起微信支付收银台

  • SDK的调用需要携带签名参与签名的参数为appid、partnerid、prepayid、package、noncestr、timestamp参数区分大小写

  • 重要入参说明

  • package取固定值Sign=WXPay

  • signType该接口V3版本仅支持RSA

  • paySign签名

paySign生成规则、响应详情及错误码请参见APP调起支付接口文档

二、支付结果回调

参照微信SDK Sample在net.sourceforge.simcpux.wxapi包路径中实现WXPayEntryActivity类(包名或类名不一致会造成无法回调)在WXPayEntryActivity类中实现onResp函数支付完成后微信APP会返回到商户APP并回调onResp函数开发者需要在该函数中接收通知判断返回错误码 如果支付成功则去后台查询支付结果再展示用户实际支付结果。注意一定不能以客户端返回作为用户支付的结果应以服务器端的接收的支付通知或查询API返回的结果为准。代码示例如下

publicvoidonResp(BaseRespresp){

    if(resp.getType()==ConstantsAPI.COMMAND_PAY_BY_WX){

    Log.d(TAG,"onPayFinish,errCode="+resp.errCode);

    AlertDialog.Builderbuilder=newAlertDialog.Builder(this);

    builder.setTitle(R.string.app_tip);

    }

}

回调中errCode值列表

名称

描述

解决方案

0

成功

展示成功页面

-1

错误

可能的原因签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。

-2

用户取消

无需处理。发生场景用户不支付了点击取消返回APP。

3.3.2.3.【服务端】接收支付结果通知

步骤说明当用户完成支付微信会把相关支付结果将通过异步回调的方式通知商户商户需要接收处理并按文档规范返回应答

注意

  • 支付结果通知是以POST 方法访问商户设置的通知url通知的数据以JSON 格式通过请求主体BODY传输。通知的数据包括了加密的支付结果详情

  • 加密不能保证通知请求来自微信。微信会对发送给商户的通知进行签名并将签名值放在通知的HTTP头Wechatpay-Signature。商户应当验证签名以确认请求来自微信而不是其他的第三方。签名验证的算法请参考 《微信支付API v3签名验证》

  • 支付通知http应答码为200或204才会当作正常接收当回调处理异常时应答的HTTP状态码应为500或者4xx

  • 商户成功接收到回调通知后应返回成功的http应答码为200或204

  • 同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是当商户系统收到通知进行处理时先检查对应业务数据的状态并判断该通知是否已经处理。如果未处理则再进行处理如果已处理则直接返回结果成功。在对业务数据进行状态检查和处理之前要采用数据锁进行并发控制以避免函数重入造成的数据混乱

  • 对后台通知交互时如果微信收到商户的应答不符合规范或超时微信认为通知失败微信会通过一定的策略定期重新发起通知尽可能提高通知的成功率但微信不保证通知最终能成功。通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序支付通知API接口文档

3.3.2.4. 【服务端】查询订单

步骤说明当商户后台、网络、服务器等出现异常商户系统最终未接收到支付通知时商户可通过查询订单接口核实订单支付状态

示例代码(通过微信订单号查询)

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/pay/transactions/id/1217752501201407033233368018?mchid=1230000109', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}

注意

  • 查询订单可通过微信支付订单号商户订单号两种方式查询两种查询方式返回结果相同

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序查询订单API接口文档

3.3.2.5. 【服务端】关闭订单

步骤说明当商户订单支付失败需要生成新单号重新发起支付要对原订单号调用关单避免重复支付系统下单后用户支付超时系统退出不再受理避免用户继续请调用关单接口

示例代码

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no}/close', //请求URL
        [
            // JSON请求体
            'json' => [
                "mchid " => "1230000109",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功无返回Body
        echo "success";
    }
  } catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
  }

3.4. 常见问题

Q微信APP支付前端调起的时候返回errcode = -1该如何排查

A1. 查看APP下单参数返回是否正常是否有正确的在调用SDK前获取了正确的prepay_id

2.查看调用SDK签名是否正确请注意以下几点

a) 参与签名的参数名大小写一定要与文档中保持一致

b) APP下单返回的签名和调用SDK使用的签名不是同一个调用SDK需要单独根据SDK参数生成签名

3. 检查客户端调用sendReqPayReq对象赋值的正确性必要时让商户提供数据若通过异步获取到后台数据比如data对象是通过异步请求得到的对象request.appId = data.appid; 实际appid属性值为空

4. 检查对应的开发配置包括iOS的appid配置Android的包名及包签名设置。

Qapp调用“唤起支付api”返回商户支付下单id非法

A请确认唤起支付参数字段名是否与文档的一致。

Q服务商模式下调用APP下单接口返回“特殊子商户未授权的产品权限”

AAPP支付需要进行单独的授权开通才可使用请前往服务商平台子商户管理中找到对应的子商户授权服务商APP支付权限。

Q调用APP下单接口返回“sub_appid与sub_mch_id不匹配”

A在调用APP下单接口前需保证子商户号与子商户APP的appid存在绑定关系请服务商前往服务商平台的子商户管理页面中操作绑定。

  1. 支付API列表

模块名称

功能列表

描述

APP支付

APP下单

通过本接口提交微信支付APP支付订单。

查询订单

通过此接口查询订单状态。

关闭订单

通过此接口关闭待支付订单。

APP调起支付

通过合单下单接口获取到发起支付的必要参数prepay_id可以按照接口定义中的规则使用微信支付提供的SDK调起APP支付。

支付结果通知

微信支付通过支付通知接口将用户支付成功消息通知给商户。

申请退款

商户可以通过该接口将支付金额退还给买家。

查询单笔退款

提交退款申请后通过调用该接口查询退款状态 。

退款结果通知

微信支付通过退款通知接口将用户退款成功消息通知给商户。

申请交易账单

商户可以通过该接口获取交易账单文件的下载地址。

申请资金账单

商户可以通过该接口获取资金账单文件的下载地址。

下载账单

通过申请交易/资金账单获取到download_url在该接口获取到对应的账单。

四.H5支付

  1. 产品介绍

1.1简介

H5支付是指商户在微信客户端外的移动端网页展示商品或服务用户在前述页面确认使用微信支付时商户发起本服务呼起微信客户端进行支付。

说明要求商户已有H5商城网站并且已经过ICP备案即可申请接入。

提醒H5支付不建议在APP端使用如需要在APP中使用微信支付请接APP支付文档详见《APP支付文档

1.2应用场景

H5支付主要用于触屏版的手机浏览器请求微信支付的场景方便从外部浏览器唤起微信支付。

用户侧使用H5支付具体操作流程如下

步骤一 用户从非微信浏览器的站点导航进入商户H5网页用户挑选需购买商品选择微信支付发起购买流程。

步骤二 进入微信客户端确认交易输入支付密码。

步骤三 支付成功用户收到支付凭证同时商户后台收到支付成功的通知。

  1. 接入前准备

2.1.选择接入模式

商户/服务商在接入前首先要判断自己公司注册区域适用的接入模式微信支付目前提供两种接入方式直连模式和服务商模式。

● 直连模式

信息、资金流微信支付—>直连商户

直连模式商户自行申请入驻微信支付无需服务商协助。商户平台申请成为直连商户

● 服务商模式

—— 信息流 —— 资金流

服务商模式商户申请成为微信支付服务商服务商自身无法作为一个直连商户直接发起交易其发起交易必须传入相关特约商户商户号的参数信息。服务商平台申请成为服务商

请结合自身实际情况来选择接入模式。

服务商模式相关说明详见服务商模式介绍

2.2.参数申请

商户自行申请入驻微信支付无服务商协助。商户平台申请成为直连商户

2.2.1申请APPID

由于微信支付的产品体系全部搭载于微信的社交体系之上所以直连商户或服务商接入微信支付之前都需要有一个微信社交载体该载体对应的ID即为APPID。

对于直连商户该社交载体可以是公众号什么是公众号小程序什么是小程序或APP。

如申请社交载体为公众号请前往 公众平台申请

如申请社交载体为小程序请前往 小程序平台 申请

如商户已拥有自己的APP且希望该APP接入微信支付请前往 开放平台申请

商户可根据实际的业务需求来选择申请不同的社交载体。

各类社交载体一旦申请成功后可以登录对应平台查看账号信息以获取对应的appid。

2.2.2申请mchid

申请mchid和APPID的操作互不影响可以并行操作申请地址如下 商户号申请平台

申请成功后会向服务商填写的联系邮箱下发通知邮件内容包含申请成功的mchid及其登录账号密码请妥善保存。

注意一个mchid只能对应一个结算币种若需要使用多个币种收款需要申请对应数量的mchid。

2.2.3绑定APPID及mchid

APPID和mchid全部申请完毕后需要建立两者之间的绑定关系。

直连模式下APPID与mchid之间的关系为多对多即一个APPID下可以绑定多个mchid而一个mchid也可以绑定多个APPID。

2.3.配置API key

API v3密钥主要用于平台证书解密、回调信息解密具体使用方式可参见接口规则文档中证书和回调报文解密章节。

请根据以下步骤配置API key

2.3.1登录微信商户平台进入【账户中心 > API安全 】目录设置APIV3密钥。

2.3.2在弹出窗口中点击“已沟通”。

2.3.3输入API密钥内容为32位字符包括数字及大小写字母。点击获取短信验证码。

2.3.4输入短信验证码点击“确认”即设置成功。

2.4.下载并配置商户证书

商户API证书具体使用说明可参见接口规则文档中私钥和证书章节

商户可登录微信商户平台在【账户中心】->【API安全】目录下载证书

以下为具体下载步骤

2.1从2018年底开始微信支付新入驻机构及商户都将使用CA签发证书在证书申请页面上点击“申请证书”。

2.2在弹出窗口中点击“确定”。

2.3在弹出窗口内点击“下载证书工具”按钮下载证书工具。

2.4安装证书工具并打开选择证书需要存储的路径后点击“申请证书”。

2.5在证书工具中将复制的商户信息粘贴并点击“下一步”。

2.6获取请求串

2.7生成证书串

步骤1 在【商户平台】-“复制证书串”环节点击“复制证书串”按钮后

步骤2 在【证书工具】-“复制请求串”环节点击“下一步”按钮进入“粘贴证书串”环节

步骤3 在【证书工具】-“粘贴证书串”环节点击“粘贴”按钮后

步骤4 点击“下一步”按钮进入【证书工具】-“生成证书”环节

2.8在【证书工具】-“生成证书”环节已完成申请证书流程点击“查看证书文件夹”查看已生成的证书文件。

2.5.H5支付开发准备

准备工作

1、H5支付域名

2、售卖产品/使用场景的描述

3、所售卖产品对应的官方网站域名或详情页网址

开通流程入驻成为商户在线提交营业执照、身份证、银行账户等基本信息快速提交申请

申请规则详见商户申请H5支付权限需要注意哪些规则

  1. 开发指引

3.1. 接口规则

为了在保证支付安全的前提下带给商户简单、一致且易用的开发体验我们推出了全新的微信支付APIv3接口。该版本API的具体规则请参考“APIv3接口规则

备注当前接口用于微信国内钱包

3.2. 开发准备

3.2.1. 搭建和配置开发环境

为了帮助开发者调用开放接口我们提供了JAVA、PHP、GO三种语言版本的开发库封装了签名生成、签名验证、敏感信息加/解密、媒体文件上传等基础功能更多语言版本的开发库将在近期陆续提供

测试步骤

1、根据自身开发语言选择对应的开发库并构建项目具体配置请参考下面链接的详细说明

wechatpay-java推荐wechatpay-apache-httpclient适用于Java开发者。

wechatpay-php推荐、wechatpay-guzzle-middleware适用于PHP开发者

注当前开发指引接口PHP示例代码采用wechatpay-guzzle-middleware版本

wechatpay-go适用于Go开发者

更多资源可前往微信支付开发者社区搜索查看

2、创建加载商户私钥、加载平台证书、初始化httpClient的通用方法

JAVA

PHP

useGuzzleHttp\Exception\RequestException;
useWechatPay\GuzzleMiddleware\WechatPayMiddleware;
useWechatPay\GuzzleMiddleware\Util\PemUtil;
useGuzzleHttp\HandlerStack;
 
// 商户相关配置
$merchantId = '1000100'; // 商户号
$merchantSerialNumber = 'XXXXXXXXXX'; // 商户API证书序列号
$merchantPrivateKey = PemUtil::loadPrivateKey('./path/to/mch/private/key.pem'); // 商户私钥文件路径// 微信支付平台配置
$wechatpayCertificate = PemUtil::loadCertificate('./path/to/wechatpay/cert.pem'); // 微信支付平台证书文件路径// 构造一个WechatPayMiddleware
$wechatpayMiddleware = WechatPayMiddleware::builder()
    ->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 传入商户相关配置
    ->withWechatPay([ $wechatpayCertificate ]) // 可传入多个微信支付平台证书参数类型为array
    ->build();
 
// 将WechatPayMiddleware添加到Guzzle的HandlerStack中
$stack = GuzzleHttp\HandlerStack::create();
$stack->push($wechatpayMiddleware, 'wechatpay');
 
// 创建Guzzle HTTP Client时将HandlerStack传入接下来正常使用Guzzle发起API请求WechatPayMiddleware会自动地处理签名和验签
$client = new GuzzleHttp\Client(['handler' => $stack]);

3、基于接口的示例代码替换请求参数后可发起测试

说明

• 上面的开发库为微信支付官方开发库其它没有审核或者控制下的第三方工具和库微信支付不保证它们的安全性和可靠性

通过包管理工具引入SDK后可根据下面每个接口的示例代码替换相关参数后进行快速测试

开发者如果想详细了解签名生成、签名验证、敏感信息加/解密、媒体文件上传等常用方法的具体代码实现可阅读下面的详细说明

1.签名生成

2.签名验证

3.敏感信息加解密

4.merchantPrivateKey私钥

5.wechatpayCertificates平台证书

6.APIV3KeyV3 key

如想更详细的了解我们的接口规则可查看我们的接口规则指引文档

3.2.2. 业务开发配置

3.2.2.1. 开通H5支付权限

● 前往微信支付商户平台—>产品中心—>H5支付—>申请开通

3.1.2.2.服务器配置要求

● 登录【微信支付商户平台—>产品中心—>开发配置—>H5支付】设置后一般10分钟内生效。

注意

  • 域名必须通过ICP备案

  • 域名填写格式不包含http://或https://

3.3. 快速接入

3.3.1. 业务流程图

安全标准规范流程图

重点步骤说明

步骤1 用户向商户系统后台请求下单商户后台必须做好安全校验

  • 当跨域请求不是简单请求时浏览器会发起Options预检请求此时商户后台需要支持Options请求且校验Origin头部如果不在允许的白名单列表内则返回403且不返回Access-Control-Allow-* 相关头部

  • 针对GET/POST的跨域下单请求商户后台需要校验Origin头部是否合法且用户Cookie是否完备若用户未登陆则先引导登陆商户站点否则返回403且不返回Access-Control-Allow-* 相关头部

步骤2 商户可通过H5下单API创建支付订单。

步骤3 用户通过微信外部的浏览器调起微信支付中间页进行发起支付请求。

步骤5 用户支付成功后商户可接收到微信支付支付结果通知支付通知API

步骤8 商户在没有接收到微信支付结果通知的情况下需要主动调用查询订单API查询支付结果。

注意

  • 商户需按照安全规范进行接入若因未遵循规范接入而出现安全问题财付通将根据《微信支付服务协议》条款处理

  • 以上图示仅为示例只供参考。请商户自行确认是否实现了跨越访问白名单限制和用户登录态校验。

3.3.2. API接入含示例代码

本文档展示了如何使用微信支付服务端 SDK 快速接入H5支付产品完成与微信支付对接的部分。

注意

  • 文档中的代码示例是用来阐述 API 基本使用方法代码中的示例参数需替换成商户自己账号及请求参数才能跑通。

  • 以下接入步骤仅提供参考请商户结合自身业务需求进行评估、修改。

3.3.2.1. 【服务端】H5下单

步骤说明用户使用微信外部的浏览器访问商户H5页面当用户选择相关商品购买时商户系统先调用该接口在微信支付服务后台生成预支付交易单。

示例代码

PHP

try {
$resp = $client->request(
    'POST',
    'https://api.mch.weixin.qq.com/v3/pay/transactions/h5', //请求URL
    [
        // JSON请求体'json' => [
            "time_expire" => "2018-06-08T10:34:56+08:00",
            "amount" => [
                "total" => 100,
                "currency" => "CNY",
            ],
            "mchid" => "1900006891",
            "description" => "Image形象店-深圳腾大-QQ公仔",
            "notify_url" => "https://www.weixin.qq.com/wxpay/pay.php",
            "out_trade_no" => "1217752501201407033233368022",
            "goods_tag" => "WXG",
            "appid" => "wxdace645e0bc2c424",
            "attach" => "自定义数据说明",
            "scene_info" => [
                "store_info" => [
                    "address" => "广东省深圳市南山区科技中一道10000号",
                    "area_code" => "440305",
                    "name" => "腾讯大厦分店",
                    "id" => "0001",
                ],
                "device_id" => "013467007045764",
                "payer_client_ip" => "14.23.150.211",
                "h5_info"=>[
                    "type"=>"IOS"
                ],
            ]
        ],
        'headers' => [ 'Accept' => 'application/json' ]
    ]
);
$statusCode = $resp->getStatusCode();
if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
} elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
}
} catch (RequestException $e) {
// 进行错误处理echo $e->getMessage()."\n";
if ($e->hasResponse()) {
    echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
}
return;
}

重要参数说明

• out_trade_no商户系统内部订单号只能是数字、大小写字母_-*且在同一个商户号下唯一

• description商品描述

• notify_url支付回调通知URL该地址必须为直接可访问的URL不允许携带查询串

• total订单总金额单位为分

• scene_info支付场景描述

更多参数、响应详情及错误码请参见H5下单API接口文档

3.3.2.2.【客户端】微信外部的浏览器拉起微信支付中间页

步骤说明通过H5下单API成功获取H5下单返回的支付中间页h5_url后用户需要通过微信外部的浏览器调起微信支付收银台

注意

  • h5_url为拉起微信支付收银台的中间页面可通过访问该url来拉起微信客户端完成支付h5_url的有效期为5分钟

  • 微信支付收银台中间页会进行H5权限的校验安全性检查

  • 需对redirect_url进行urlencode处理

  • 由于设置redirect_url后,回跳指定页面的操作可能发生在

1、微信支付中间页调起微信收银台后超过5秒

2、用户点击“取消支付”或支付完成后点击“完成”按钮。因此无法保证页面回跳时支付流程已结束所以商户设置的redirect_url地址不能自动执行查单操作应让用户去点击按钮触发查单操作回跳页面展示效果可参考下图

3.3.2.3.【服务端】接收支付结果通知

步骤说明当用户完成支付微信会把相关支付结果将通过异步回调的方式通知商户商户需要接收处理并按文档规范返回应答

注意

  • 支付结果通知是以POST 方法访问商户设置的通知url通知的数据以JSON 格式通过请求主体BODY传输。通知的数据包括了加密的支付结果详情

  • 加密不能保证通知请求来自微信。微信会对发送给商户的通知进行签名并将签名值放在通知的HTTP头Wechatpay-Signature。商户应当验证签名以确认请求来自微信而不是其他的第三方。签名验证的算法请参考 《微信支付API v3签名验证》

  • 支付通知http应答码为200或204才会当作正常接收当回调处理异常时应答的HTTP状态码应为500或者4xx

  • 商户成功接收到回调通知后应返回成功的http应答码为200或204

  • 同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是当商户系统收到通知进行处理时先检查对应业务数据的状态并判断该通知是否已经处理。如果未处理则再进行处理如果已处理则直接返回结果成功。在对业务数据进行状态检查和处理之前要采用数据锁进行并发控制以避免函数重入造成的数据混乱

  • 对后台通知交互时如果微信收到商户的应答不符合规范或超时微信认为通知失败微信会通过一定的策略定期重新发起通知尽可能提高通知的成功率但微信不保证通知最终能成功。通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序支付通知API接口文档

3.3.2.4. 【服务端】查询订单

步骤说明当商户后台、网络、服务器等出现异常商户系统最终未接收到支付通知时商户可通过查询订单接口核实订单支付状态

示例代码(通过微信订单号查询)

PHP

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/pay/transactions/id/1217752501201407033233368018?mchid=1230000109', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
} catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}

注意

  • 查询订单可通过微信支付订单号商户订单号两种方式查询两种查询方式返回结果相同

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序查询订单API接口文档

3.3.2.5. 【服务端】关闭订单

步骤说明当商户订单支付失败需要生成新单号重新发起支付要对原订单号调用关单避免重复支付系统下单后用户支付超时系统退出不再受理避免用户继续请调用关单接口

示例代码

PHP

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no}/close', //请求URL
        [
            // JSON请求体'json' => [
                "mchid " => "1230000109",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
  } catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
  }
  

注意

  • 订单生成后不能马上调用关单接口最短调用时间间隔为5分钟

  • 已支付成功的订单不能关闭

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序接口文档

3.3.2.6. 【服务端】申请交易账单

步骤说明微信支付按天提供交易账单文件商户可以通过该接口获取账单文件的下载地址

示例代码

PHP

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/bill/tradebill?bill_date=2019-06-11&bill_type=ALL', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
} catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

注意

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序接口文档

3.3.2.7. 【服务端】下载账单

步骤说明通过申请交易账单接口获取到账单下载地址download_url后再通过该接口获取到对应的账单文件文件内包含交易相关的金额、时间、营销等信息供商户核对订单、退款、银行到账等情况

示例代码

PHP

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/billdownload/file?token=xx', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
} catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}

注意

• 账单文件的下载地址的有效时间为30s

• 强烈建议商户将实际账单文件的哈希值和之前从接口获取到的哈希值进行比对以确认数据的完整性

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序下载账单API接口文档

3.4. 常见问题

Q调起H5支付报"商家参数格式有误请联系商家解决"

A请按以下几点进行排查

1. 当前调起H5支付的referer为空导致一般是因为直接访问页面调起H5支付请按正常流程进行页面跳转后发起支付或自行抓包确认referer值是否为空

2. 如果是APP里调起H5支付需要在webview中手动设置referer如(Map extraHeaders = new HashMap();extraHeaders.put("Referer", "商户申请H5时提交的授权域名");//例如 https://pay.weixin.qq.com )

Q调起H5支付报"商家存在未配置的参数请联系商家解决"

A请按以下几点进行排查

1当前调起H5支付的域名微信侧从referer中获取与申请H5支付时提交的授权域名不一致如需添加或修改授权域名请登录商户号对应的【商户平台 -> 产品中心 -> 开发配置】自行配置

2如果设置了回跳地址redirect_url请确认设置的回跳地址的域名与申请H5支付时提交的授权域名是否一致

Q调起H5支付报"支付请求已失效请重新发起支付"

AH5下单返回的H5_URL生成后有效期为5分钟如超时请重新生成H5_URL后再发起支付

Q调起H5支付报" 请在微信外打开订单进行支付"

AH5支付不能直接在微信客户端内调起请在外部浏览器调起

Q调起H5支付报" 签名验证失败"或“系统繁忙请稍后再试”

A请按以下几点进行排查

1请确认同一个H5_URL只被一个微信号调起如果不同微信号调起请重新下单生成新的H5_URL

2如H5_URL有添加redirect_url请确认参数拼接格式是否有误是否有对redirect_url的值做urlencode,可参考以下例子格式

https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096&redirect_url=https%3A%2F%2Fwww.wechatpay.com.cn

QIOS在使用某些浏览器完成H5支付后会回到safari浏览器

A完成H5支付后需通过schame信息返回调起支付的浏览器但由于部分浏览器隐藏了这个信息在无法拿到schame信息的情况下就会默认回到safari浏览器

  1. 支付API列表

模块名称

功能列表

描述

H5支付

H5下单

通过本接口提交微信支付H5支付订单。

查询订单

通过此接口查询订单状态。

关闭订单

通过此接口关闭待支付订单。

H5调起支付

调用微信支付的H5支付接口微信后台系统返回链接参数h5_url商户通过h5_url调起微信支付中间页。

支付结果通知

微信支付通过支付通知接口将用户支付成功消息通知给商户。

申请退款

商户可以通过该接口将支付金额退还给买家。

查询单笔退款

提交退款申请后通过调用该接口查询退款状态 。

退款结果通知

微信支付通过退款通知接口将用户退款成功消息通知给商户。

申请交易账单

商户可以通过该接口获取交易账单文件的下载地址。

申请资金账单

商户可以通过该接口获取资金账单文件的下载地址。

下载账单

通过申请交易/资金账单获取到download_url在该接口获取到对应的账单。

五.Native支付

  1. 产品介绍

1.1简介

Native支付是指商户系统按微信支付协议生成支付二维码用户再用微信“扫一扫”完成支付的模式。

1.2应用场景

Native支付适用于PC网站、实体店单品或订单、媒体广告支付等场景

用户扫描商户展示在各种场景的二维码进行支付具体操作流程如下

步骤一 商户根据微信支付的规则为不同商品生成不同的二维码如图3.1展示在各种场景用于用户扫描购买。

步骤二 用户使用微信“扫一扫”如图3.2扫描二维码后获取商品支付信息引导用户完成支付如图3.3。

图3.1 支付二维码

图3.2 打开微信扫一扫二维码

图3.3 确认支付页面

步骤三 用户确认支付输入支付密码如图3.4。

步骤四 支付完成后会提示用户支付成功如图3.5商户后台得到支付成功的通知然后进行发货处理。

图3.4 用户确认支付输入密码

图3.5 支付成功提示

  1. 接入前准备

2.1.选择接入模式

商户/服务商在接入前首先要判断自己公司注册区域适用的接入模式微信支付目前提供两种接入方式直连模式和服务商模式。

● 直连模式

信息、资金流微信支付—>直连商户

直连模式商户自行申请入驻微信支付无需服务商协助。商户平台申请成为直连商户

● 服务商模式

—— 信息流 —— 资金流

服务商模式商户申请成为微信支付服务商服务商自身无法作为一个直连商户直接发起交易其发起交易必须传入相关特约商户商户号的参数信息。服务商平台申请成为服务商

请结合自身实际情况来选择接入模式。

服务商模式相关说明详见服务商模式介绍

2.2.参数申请

商户自行申请入驻微信支付无服务商协助。商户平台申请成为直连商户

2.2.1申请APPID

由于微信支付的产品体系全部搭载于微信的社交体系之上所以直连商户或服务商接入微信支付之前都需要有一个微信社交载体该载体对应的ID即为APPID。

对于直连商户该社交载体可以是公众号什么是公众号小程序什么是小程序或APP。

如申请社交载体为公众号请前往 公众平台申请

如申请社交载体为小程序请前往 小程序平台 申请

如商户已拥有自己的APP且希望该APP接入微信支付请前往 开放平台申请

商户可根据实际的业务需求来选择申请不同的社交载体。

各类社交载体一旦申请成功后可以登录对应平台查看账号信息以获取对应的appid。

2.2.2申请mchid

申请mchid和APPID的操作互不影响可以并行操作申请地址如下 商户号申请平台

申请成功后会向服务商填写的联系邮箱下发通知邮件内容包含申请成功的mchid及其登录账号密码请妥善保存。

注意一个mchid只能对应一个结算币种若需要使用多个币种收款需要申请对应数量的mchid。

2.2.3绑定APPID及mchid

APPID和mchid全部申请完毕后需要建立两者之间的绑定关系。

直连模式下APPID与mchid之间的关系为多对多即一个APPID下可以绑定多个mchid而一个mchid也可以绑定多个APPID。

2.3.配置API key

API v3密钥主要用于平台证书解密、回调信息解密具体使用方式可参见接口规则文档中证书和回调报文解密章节。

请根据以下步骤配置API key

2.3.1登录微信商户平台进入【账户中心 > API安全 】目录设置APIV3密钥。

2.3.2在弹出窗口中点击“已沟通”。

2.3.3输入API密钥内容为32位字符包括数字及大小写字母。点击获取短信验证码。

2.3.4输入短信验证码点击“确认”即设置成功。

2.4.下载并配置商户证书

商户API证书具体使用说明可参见接口规则文档中私钥和证书章节

商户可登录微信商户平台在【账户中心】->【API安全】目录下载证书

以下为具体下载步骤

2.4.1从2018年底开始微信支付新入驻机构及商户都将使用CA签发证书在证书申请页面上点击“申请证书”。

2.4.2在弹出窗口中点击“确定”。

2.4.3在弹出窗口内点击“下载证书工具”按钮下载证书工具。

2.4.4安装证书工具并打开选择证书需要存储的路径后点击“申请证书”。

2.4.5在证书工具中将复制的商户信息粘贴并点击“下一步”。

2.4.6获取请求串

2.4.7生成证书串

步骤1 在【商户平台】-“复制证书串”环节点击“复制证书串”按钮后

步骤2 在【证书工具】-“复制请求串”环节点击“下一步”按钮进入“粘贴证书串”环节

步骤3 在【证书工具】-“粘贴证书串”环节点击“粘贴”按钮后

步骤4 点击“下一步”按钮进入【证书工具】-“生成证书”环节

2.4.8在【证书工具】-“生成证书”环节已完成申请证书流程点击“查看证书文件夹”查看已生成的证书文件。

2.5. Native支付设计指引

线上扫码收银台界面规范

示例1单独显要区域常驻微信支付

示例2单独页签+页签首位+新logo+推荐标签+直接二维码

开通流程在入驻时选择PC网站场景的商户系统默认开通此功能其他商户如有需要可以在入驻后前往商户平台-产品中心-Native支付-申请开通。

  1. 开发指引

3.1. 接口规则

为了在保证支付安全的前提下带给商户简单、一致且易用的开发体验我们推出了全新的微信支付APIv3接口。该版本API的具体规则请参考“APIv3接口规则

备注当前接口用于微信国内钱包

3.2. 开发准备

3.2.1. 搭建和配置开发环境

为了帮助开发者调用开放接口我们提供了JAVA、PHP、GO三种语言版本的开发库封装了签名生成、签名验证、敏感信息加/解密、媒体文件上传等基础功能更多语言版本的开发库将在近期陆续提供

测试步骤

1、根据自身开发语言选择对应的开发库并构建项目具体配置请参考下面链接的详细说明

wechatpay-java推荐wechatpay-apache-httpclient适用于Java开发者。

wechatpay-php推荐、wechatpay-guzzle-middleware适用于PHP开发者

注当前开发指引接口PHP示例代码采用wechatpay-guzzle-middleware版本

wechatpay-go适用于Go开发者

更多资源可前往微信支付开发者社区搜索查看

2、创建加载商户私钥、加载平台证书、初始化httpClient的通用方法

JAVA

PHP

useGuzzleHttp\Exception\RequestException;
useWechatPay\GuzzleMiddleware\WechatPayMiddleware;
useWechatPay\GuzzleMiddleware\Util\PemUtil;
useGuzzleHttp\HandlerStack;
 
// 商户相关配置
$merchantId = '1000100'; // 商户号
$merchantSerialNumber = 'XXXXXXXXXX'; // 商户API证书序列号
$merchantPrivateKey = PemUtil::loadPrivateKey('./path/to/mch/private/key.pem'); // 商户私钥文件路径// 微信支付平台配置
$wechatpayCertificate = PemUtil::loadCertificate('./path/to/wechatpay/cert.pem'); // 微信支付平台证书文件路径// 构造一个WechatPayMiddleware
$wechatpayMiddleware = WechatPayMiddleware::builder()
    ->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 传入商户相关配置
    ->withWechatPay([ $wechatpayCertificate ]) // 可传入多个微信支付平台证书参数类型为array
    ->build();
 
// 将WechatPayMiddleware添加到Guzzle的HandlerStack中
$stack = GuzzleHttp\HandlerStack::create();
$stack->push($wechatpayMiddleware, 'wechatpay');
 
// 创建Guzzle HTTP Client时将HandlerStack传入接下来正常使用Guzzle发起API请求WechatPayMiddleware会自动地处理签名和验签
$client = new GuzzleHttp\Client(['handler' => $stack]);

3、基于接口的示例代码替换请求参数后可发起测试

说明

• 上面的开发库为微信支付官方开发库其它没有审核或者控制下的第三方工具和库微信支付不保证它们的安全性和可靠性

通过包管理工具引入SDK后可根据下面每个接口的示例代码替换相关参数后进行快速测试

开发者如果想详细了解签名生成、签名验证、敏感信息加/解密、媒体文件上传等常用方法的具体代码实现可阅读下面的详细说明

1.签名生成

2.签名验证

3.敏感信息加解密

4.merchantPrivateKey私钥

5.wechatpayCertificates平台证书

6.APIV3KeyV3 key

如想更详细的了解我们的接口规则可查看我们的接口规则指引文档

3.3. 快速接入

3.3.1. 业务流程图

重点步骤说明

步骤2用户确认支付后商户调用微信支付Native下单API生成预支付交易以获取支付二维码链接code_url

商户调用NativeNative下单API后分正常返回和异常返回情况

  • 正常返回返回code_url商户可根据返回的code_url来生成调用OpenSDK的签名以执行下一步。

步骤4 商户根据返回的code_url生成二维码供用户扫描有关二维码的规则请参考3.2.2部分的说明

步骤9-11: 用户支付成功后商户可通过以下两种方式获取订单状态

方法一支付结果通知。用户支付成功后微信支付会将支付成功的结果以回调通知的形式同步给商户商户的回调地址需要在调用Native下单API时传入notify_url参数。

方法二当因网络抖动或本身notify_url存在问题等原因导致无法接收到回调通知时商户也可主动调用查询订单API来获取订单状态

3.3.2. API接入含示例代码

本章节展示了如何使用微信支付服务端 SDK 快速接入Native支付产品完成与微信支付对接的部分。

注意

  • 文档中的代码示例是用来阐述 API 基本使用方法代码中的示例参数需替换成商户自己账号及参数才能调试成功。

  • 以下接入步骤仅提供参考请商户结合实际业务需求进行评估、修改。

3.3.2.1. 【服务端】Native下单

步骤说明用户在商户PC网站内完成商品选择后进入支付页面商户需要通过后端请求该Native下单API来获取支付二维码链接code_url。

示例代码

PHP

try {
$resp = $client->request(
    'POST',
    'https://api.mch.weixin.qq.com/v3/pay/transactions/native', //请求URL
    [
        // JSON请求体'json' => [
            "time_expire" => "2018-06-08T10:34:56+08:00", 
            "amount" => [
                "total" => 100, 
                "currency" => "CNY", 
            ],
            "mchid" => "1230000109", 
            "description" => "Image形象店-深圳腾大-QQ公仔", 
            "notify_url" => "https://www.weixin.qq.com/wxpay/pay.php", 
            "out_trade_no" => "1217752501201407033233368018", 
            "goods_tag" => "WXG", 
            "appid" => "wxd678efh567hg6787", 
            "attach" => "自定义数据说明", 
            "detail" => [
                "invoice_id" => "wx123", 
                "goods_detail" => [
                    [
                        "goods_name" => "iPhoneX 256G", 
                        "wechatpay_goods_id" => "1001", 
                        "quantity" => 1, 
                        "merchant_goods_id" => "商品编码", 
                        "unit_price" => 828800, 
                    ],
                    [
                        "goods_name" => "iPhoneX 256G", 
                        "wechatpay_goods_id" => "1001", 
                        "quantity" => 1, 
                        "merchant_goods_id" => "商品编码", 
                        "unit_price" => 828800, 
                    ],
                ],
                "cost_price" => 608800, 
            ],
            "scene_info" => [
                "store_info" => [
                    "address" => "广东省深圳市南山区科技中一道10000号", 
                    "area_code" => "440305", 
                    "name" => "腾讯大厦分店", 
                    "id" => "0001", 
                ],
                "device_id" => "013467007045764", 
                "payer_client_ip" => "14.23.150.211", 
            ]
        ],
        'headers' => [ 'Accept' => 'application/json' ]
    ]
);
$statusCode = $resp->getStatusCode();
if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
} elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
}
} catch (RequestException $e) {
// 进行错误处理echo $e->getMessage()."\n";
if ($e->hasResponse()) {
    echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
}
return;

}

重要参数说明

• out_trade_no商户系统内部订单号只能是数字、大小写字母_-*且在同一个商户号下唯一

• description商品描述

• notify_url支付回调通知URL该地址必须为直接可访问的URL不允许携带查询串

• total订单总金额单位为分

更多参数、响应详情及错误码请参见Native下单API接口文档

3.3.2.2. 【客户端】生成支付二维码

步骤说明通过Native下单API成功获取支付二维码链接code_url后需要在前端PC网页或POS机具生成二维码供用户扫描支付。

注意

例如weixin//weixin://pay.weixin.qq.com/bizpayurl/up?pr=NwY5Mz9&groupid=00 生成二维码见下图

  • 更多二维码的相关背景知识可参考

https://www.qrcode.com/zh/index.html

3.3.2.3.【服务端】接收支付结果通知

步骤说明当用户完成支付微信会把相关支付结果将通过异步回调的方式通知商户商户需要接收处理并按文档规范返回应答

注意

  • 支付结果通知是以POST 方法访问商户设置的通知url通知的数据以JSON 格式通过请求主体BODY传输。通知的数据包括了加密的支付结果详情

  • 加密不能保证通知请求来自微信。微信会对发送给商户的通知进行签名并将签名值放在通知的HTTP头Wechatpay-Signature。商户应当验证签名以确认请求来自微信而不是其他的第三方。签名验证的算法请参考 《微信支付API v3签名验证》

  • 支付通知http应答码为200或204才会当作正常接收当回调处理异常时应答的HTTP状态码应为500或者4xx

  • 商户成功接收到回调通知后应返回成功的http应答码为200或204

  • 同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是当商户系统收到通知进行处理时先检查对应业务数据的状态并判断该通知是否已经处理。如果未处理则再进行处理如果已处理则直接返回结果成功。在对业务数据进行状态检查和处理之前要采用数据锁进行并发控制以避免函数重入造成的数据混乱

  • 对后台通知交互时如果微信收到商户的应答不符合规范或超时微信认为通知失败微信会通过一定的策略定期重新发起通知尽可能提高通知的成功率但微信不保证通知最终能成功。通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序支付通知API接口文档

3.3.2.4. 【服务端】查询订单

步骤说明当商户后台、网络、服务器等出现异常商户系统最终未接收到支付通知时商户可通过查询订单接口核实订单支付状态

示例代码(通过微信订单号查询)

PHP

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/pay/transactions/id/1217752501201407033233368018?mchid=1230000109', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
} catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}

注意

  • 查询订单可通过微信支付订单号商户订单号两种方式查询两种查询方式返回结果相同

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序查询订单API接口文档

3.3.2.5. 【服务端】关闭订单

步骤说明当商户订单支付失败需要生成新单号重新发起支付要对原订单号调用关单避免重复支付系统下单后用户支付超时系统退出不再受理避免用户继续请调用关单接口

示例代码

PHP

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no}/close', //请求URL
        [
            // JSON请求体'json' => [
                "mchid " => "1230000109",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
  } catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
  }
  

注意

  • 订单生成后不能马上调用关单接口最短调用时间间隔为5分钟

  • 已支付成功的订单不能关闭

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序接口文档

3.3.2.6. 【服务端】申请交易账单

步骤说明微信支付按天提供交易账单文件商户可以通过该接口获取账单文件的下载地址

示例代码

PHP

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/bill/tradebill?bill_date=2019-06-11&bill_type=ALL', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
} catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

注意

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序接口文档

3.3.2.7. 【服务端】下载账单

步骤说明通过申请交易账单接口获取到账单下载地址download_url后再通过该接口获取到对应的账单文件文件内包含交易相关的金额、时间、营销等信息供商户核对订单、退款、银行到账等情况

示例代码

PHP

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/billdownload/file?token=xx', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
} catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}

注意

• 账单文件的下载地址的有效时间为30s

• 强烈建议商户将实际账单文件的哈希值和之前从接口获取到的哈希值进行比对以确认数据的完整性

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序下载账单API接口文档

3.4. 常见问题

Q微信native支付生成的二维码有有效期吗?

一个二维码的有效期是根据Native下单接口返回的code_url决定code_url的有效期是2小时。

Qnative支付扫码后提示支付失败该商户暂不支持通过长按识别二维码完成支付

A微信支付已经不支持通过长按识别二维码的方式或通过相册识别二维码的方式完成支付。

  1. 支付API列表

模块名称

功能列表

描述

Native支付

Native下单

通过本接口提交微信支付Native支付订单。

查询订单

通过此接口查询订单状态。

关闭订单

通过此接口关闭待支付订单。

Native调起支付

商户后台系统先调用微信支付的Native支付接口微信后台系统返回链接参数code_url商户后台系统将code_url值生成二维码图片用户使用微信客户端扫码后发起支付。

支付结果通知

微信支付通过支付通知接口将用户支付成功消息通知给商户。

申请退款

商户可以通过该接口将支付金额退还给买家。

查询单笔退款

提交退款申请后通过调用该接口查询退款状态 。

退款结果通知

微信支付通过退款通知接口将用户退款成功消息通知给商户。

申请交易账单

商户可以通过该接口获取交易账单文件的下载地址。

申请资金账单

商户可以通过该接口获取资金账单文件的下载地址。

下载账单

通过申请交易/资金账单获取到download_url在该接口获取到对应的账单。

六.小程序支付

  1. 产品介绍

1.1简介

商户已有微信小程序用户通过好友分享或扫描二维码在微信内打开小程序时可以调用微信支付完成下单购买的流程。

注意小程序不能通过拉起H5页面做jsapi支付小程序内只能使用小程序支付

1.2用户付款流程

步骤1如图1用户通过分享或扫描二维码进入商户小程序用户选择购买完成选购流程。

步骤2如图3调起微信支付控件用户开始输入支付密码。

图1 打开商户小程序

图2 请求微信支付

图3 调起微信支付控件

步骤3如图4密码验证通过支付成功。商户后台得到支付成功的通知。

步骤4如图5返回商户小程序显示购买成功。

步骤5如图6微信支付公众号下发支付凭证。

图4 请求支付成功

图5 返回商户小程序

图6 下发支付凭证

1.3业务场景结合

了解完微信支付不同模式的基础账号关系与使用后针对第三方模式进行枚举说明以小程序举例。

小程序的开发第三方服务商帮商户开发小程序有三种业务场景:

1、第三方自己申请账号自己开发生成指定内页给特约商户用该模式简称中心化模式。

2、以特约商户身份申请小程序appid第三方完成开发该模式简称外包模式。

3、通过开放平台第三方开发者代特约商户进行小程序的开发该模式简称第三方模式。

无论哪种模式开发的小程序在使用面对用户的微信支付能力时都以该小程序appid为主体id来调用微信开放平台提供的api。

以在某小程序中发起微信支付为例分后台下单和前端js拉起收银台两部分。

其中后台下单对应微信支付的三大类开放模式前端js拉起收银台需通过该小程序的appid且该appid参与后台下单。即根据不同的开放模式和业务场景枚举第三方开发小程序使用微信支付时可分为9种3*3不同的组合模式结合实际业务诉求选择对应的组合模式进行开发。

注意以上3*3共计9种组合均能成功接入微信支付。但红色连接线为二清模式政策上不允许采用该模式。有需求的第三方开发者可通过银行渠道商模式接入。

  1. 接入前准备

2.1.选择接入模式

商户/服务商在接入前首先要判断自己公司注册区域适用的接入模式微信支付目前提供两种接入方式直连模式和服务商模式。

● 直连模式

信息、资金流微信支付—>直连商户

直连模式商户自行申请入驻微信支付无需服务商协助。商户平台申请成为直连商户

● 服务商模式

—— 信息流 —— 资金流

服务商模式商户申请成为微信支付服务商服务商自身无法作为一个直连商户直接发起交易其发起交易必须传入相关特约商户商户号的参数信息。服务商平台申请成为服务商

请结合自身实际情况来选择接入模式。

服务商模式相关说明详见服务商模式介绍

2.2.参数申请

商户自行申请入驻微信支付无服务商协助。商户平台申请成为直连商户

2.1申请APPID

由于微信支付的产品体系全部搭载于微信的社交体系之上所以直连商户或服务商接入微信支付之前都需要有一个微信社交载体该载体对应的ID即为APPID。

对于直连商户该社交载体可以是公众号什么是公众号小程序什么是小程序或APP。

如申请社交载体为公众号请前往 公众平台申请

如申请社交载体为小程序请前往 小程序平台 申请

如商户已拥有自己的APP且希望该APP接入微信支付请前往 开放平台申请

商户可根据实际的业务需求来选择申请不同的社交载体。

各类社交载体一旦申请成功后可以登录对应平台查看账号信息以获取对应的appid。

2.2申请mchid

申请mchid和APPID的操作互不影响可以并行操作申请地址如下 商户号申请平台

申请成功后会向服务商填写的联系邮箱下发通知邮件内容包含申请成功的mchid及其登录账号密码请妥善保存。

注意一个mchid只能对应一个结算币种若需要使用多个币种收款需要申请对应数量的mchid。

2.3绑定APPID及mchid

APPID和mchid全部申请完毕后需要建立两者之间的绑定关系。

直连模式下APPID与mchid之间的关系为多对多即一个APPID下可以绑定多个mchid而一个mchid也可以绑定多个APPID。

2.3.配置API key

API v3密钥主要用于平台证书解密、回调信息解密具体使用方式可参见接口规则文档中证书和回调报文解密章节。

请根据以下步骤配置API key

2.3.1登录微信商户平台进入【账户中心 > API安全 】目录设置APIV3密钥。

2.3.2在弹出窗口中点击“已沟通”。

2.3.3输入API密钥内容为32位字符包括数字及大小写字母。点击获取短信验证码。

2.3.4输入短信验证码点击“确认”即设置成功。

2.4.下载并配置商户证书

商户API证书具体使用说明可参见接口规则文档中私钥和证书章节

商户可登录微信商户平台在【账户中心】->【API安全】目录下载证书

以下为具体下载步骤

2.4.1从2018年底开始微信支付新入驻机构及商户都将使用CA签发证书在证书申请页面上点击“申请证书”。

2.4.2在弹出窗口中点击“确定”。

2.4.3在弹出窗口内点击“下载证书工具”按钮下载证书工具。

2.4.4安装证书工具并打开选择证书需要存储的路径后点击“申请证书”。

2.4.5在证书工具中将复制的商户信息粘贴并点击“下一步”。

2.4.6获取请求串

2.4.7生成证书串

步骤1 在【商户平台】-“复制证书串”环节点击“复制证书串”按钮后

步骤2 在【证书工具】-“复制请求串”环节点击“下一步”按钮进入“粘贴证书串”环节

步骤3 在【证书工具】-“粘贴证书串”环节点击“粘贴”按钮后

步骤4 点击“下一步”按钮进入【证书工具】-“生成证书”环节

2.4.8在【证书工具】-“生成证书”环节已完成申请证书流程点击“查看证书文件夹”查看已生成的证书文件。

2.5.配置应用

账号申请指引

1、申请小程序开发者账号进行微信认证获取appid登录《微信公众平台》注册一个小程序的开发者账号。小程序账号申请指引

2、小程序开通微信支付即申请或复用微信支付商户号申请完小程序后登录小程序后台。点击左侧导航栏的微信支付在页面中进行开通。

点击开通按钮后有2种方式可以获取微信支付能力新申请微信支付商户号或绑定一个已有的微信支付商户号请根据你的业务需要和具体情况选择只能二选一。

  1. 开发指引

3.1. 接口规则

为了在保证支付安全的前提下带给商户简单、一致且易用的开发体验我们推出了全新的微信支付APIv3接口。该版本API的具体规则请参考“APIv3接口规则

备注当前接口用于微信国内钱包

3.2. 开发准备

3.2.1. 搭建和配置开发环境

为了帮助开发者调用开放接口我们提供了JAVA、PHP、GO三种语言版本的开发库封装了签名生成、签名验证、敏感信息加/解密、媒体文件上传等基础功能更多语言版本的开发库将在近期陆续提供

测试步骤

1、根据自身开发语言选择对应的开发库并构建项目具体配置请参考下面链接的详细说明

wechatpay-java推荐wechatpay-apache-httpclient适用于Java开发者。

wechatpay-php推荐、wechatpay-guzzle-middleware适用于PHP开发者

注当前开发指引接口PHP示例代码采用wechatpay-guzzle-middleware版本

wechatpay-go适用于Go开发者

更多资源可前往微信支付开发者社区搜索查看

2、创建加载商户私钥、加载平台证书、初始化httpClient的通用方法

JAVA

PHP

useGuzzleHttp\Exception\RequestException;
useWechatPay\GuzzleMiddleware\WechatPayMiddleware;
useWechatPay\GuzzleMiddleware\Util\PemUtil;
useGuzzleHttp\HandlerStack;
 
// 商户相关配置
$merchantId = '1000100'; // 商户号
$merchantSerialNumber = 'XXXXXXXXXX'; // 商户API证书序列号
$merchantPrivateKey = PemUtil::loadPrivateKey('./path/to/mch/private/key.pem'); // 商户私钥文件路径// 微信支付平台配置
$wechatpayCertificate = PemUtil::loadCertificate('./path/to/wechatpay/cert.pem'); // 微信支付平台证书文件路径// 构造一个WechatPayMiddleware
$wechatpayMiddleware = WechatPayMiddleware::builder()
    ->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 传入商户相关配置
    ->withWechatPay([ $wechatpayCertificate ]) // 可传入多个微信支付平台证书参数类型为array
    ->build();
 
// 将WechatPayMiddleware添加到Guzzle的HandlerStack中
$stack = GuzzleHttp\HandlerStack::create();
$stack->push($wechatpayMiddleware, 'wechatpay');
 
// 创建Guzzle HTTP Client时将HandlerStack传入接下来正常使用Guzzle发起API请求WechatPayMiddleware会自动地处理签名和验签
$client = new GuzzleHttp\Client(['handler' => $stack]);

3、基于接口的示例代码替换请求参数后可发起测试

说明

• 上面的开发库为微信支付官方开发库其它没有审核或者控制下的第三方工具和库微信支付不保证它们的安全性和可靠性

通过包管理工具引入SDK后可根据下面每个接口的示例代码替换相关参数后进行快速测试

开发者如果想详细了解签名生成、签名验证、敏感信息加/解密、媒体文件上传等常用方法的具体代码实现可阅读下面的详细说明

1.签名生成

2.签名验证

3.敏感信息加解密

4.merchantPrivateKey私钥

5.wechatpayCertificates平台证书

6.APIV3KeyV3 key

如想更详细的了解我们的接口规则可查看我们的接口规则指引文档

3.2.2. 业务开发配置

3.2.2.1.账号申请指引

a、小程序开通微信支付即申请或复用微信支付商户号申请完小程序后登录小程序后台。点击左侧导航栏的微信支付在页面中进行开通。开通申请要求小程序已发布上线

b、点击开通按钮后有2种方式可以获取微信支付能力新申请微信支付商户号或绑定一个已有的微信支付商户号请根据你的业务需要和具体情况选择只能二选一。开通指引

3.2.2.2.服务器配置要求

a、小程序访问商户服务都是通过HTTPS,开发部署的时候需要HTTPS服务器

b、服务器域名配置

①、每个微信小程序需要事先设置通信域名小程序只可以跟指定的域名进行网络通信。包括普通 HTTPS 请求wx.request、上传文件wx.uploadFile、下载文件wx.downloadFile和 WebSocket 通信wx.connectSocket

②、从基础库 2.4.0 开始网络接口允许与局域网 IP 通信但要注意 不允许与本机 IP 通信

注意

  • 域名只支持 https (wx.request、wx.uploadFile、wx.downloadFile) 和 wss (wx.connectSocket) 协议

  • 域名不能使用 IP 地址小程序的局域网 IP 除外或 localhost

  • 域名必须经过 ICP 备案

  • 出于安全考虑api.weixin.qq.com 不能被配置为服务器域名相关API也不能在小程序内调用。 开发者应将 AppSecret 保存到后台服务器中通过服务器使用 getAccessToken 接口获取 access_token并调用相关 API

  • 不支持配置父域名使用子域名

3.3. 快速接入

3.3.1. 业务流程图

重点步骤说明

步骤4用户下单发起支付商户可通过JSAPI下单创建支付订单。

步骤9商户小程序内使用小程序调起支付APIwx.requestPayment发起微信支付详见小程序API文档

步骤16用户支付成功后商户可接收到微信支付支付结果通知支付通知API

步骤21商户在没有接收到微信支付结果通知的情况下需要主动调用查询订单API查询支付结果。

3.3.2. API接入含示例代码

本章节展示了如何使用微信支付服务端 SDK 快速接入小程序支付产品完成与微信支付对接的部分。

注意

  • 文档中的代码示例是用来阐述 API 基本使用方法代码中的示例参数需替换成商户自己账号及请求参数才能跑通。

  • 以下接入步骤仅提供参考请商户结合自身业务需求进行评估、修改。

3.3.2.1. 【服务端】小程序下单

步骤说明用户通过商户小程序进入商户网页当用户选择相关商品购买时商户系统先调用该接口在微信支付服务后台生成预支付交易单。

示例代码

PHP

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi', //请求URL
        [
            // JSON请求体'json' => [
                "time_expire" => "2018-06-08T10:34:56+08:00",
                "amount" => [
                    "total" => 100,
                    "currency" => "CNY",
                ],
                "mchid" => "1230000109",
                "description" => "Image形象店-深圳腾大-QQ公仔",
                "notify_url" => "https://www.weixin.qq.com/wxpay/pay.php",
                "payer" => [
                    "openid" => "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o",
                ],
                "out_trade_no" => "1217752501201407033233368018",
                "goods_tag" => "WXG",
                "appid" => "wxd678efh567hg6787",
                "attach" => "自定义数据说明",
                "scene_info" => [
                    "store_info" => [
                        "address" => "广东省深圳市南山区科技中一道10000号",
                        "area_code" => "440305",
                        "name" => "腾讯大厦分店",
                        "id" => "0001",
                    ],
                    "device_id" => "013467007045764",
                    "payer_client_ip" => "14.23.150.211",
                ]
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
} catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}

重要参数说明

• out_trade_no商户系统内部订单号只能是数字、大小写字母_-*且在同一个商户号下唯一

• description商品描述

• notify_url支付回调通知URL该地址必须为直接可访问的URL不允许携带查询串

• total订单总金额单位为分

• openidopenid是微信用户在appid下的唯一用户标识appid不同则获取到的openid就不同可用于永久标记一个用户。openid获取方式请参考以下文档 小程序获取openid公众号获取openidAPP获取openid

更多参数、响应详情及错误码请参见JSAPI下单接口文档

3.3.2.2.【客户端】小程序调起支付API

步骤说明通过JSAPI下单成功获取预支付交易会话标识prepay_id后需要通过小程序调起支付API来调起微信支付收银台

注意

  • 此API需要将请求参数进行签名参与签名的参数为appId、timeStamp、nonceStr、package参数区分大小写

  • appId必须为最后拉起收银台的小程序appid

示例代码

wx.requestPayment(
{
"timeStamp": "1414561699",
"nonceStr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
"package": "prepay_id=wx201410272009395522657a690389285100",
"signType": "RSA",
"paySign": "oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ\/X+QBhcCYL21N7cHCTUxbQ+EAt6Uy+lwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuT+Cdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZV+JSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8Fu+LozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2+AehHvz+n64GDmXxbX++IOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq\/xDg==",
"success":function(res){},
"fail":function(res){},
"complete":function(res){}
})

• package小程序下单接口返回的prepay_id参数值提交格式如prepay_id=***

• signType该接口V3版本仅支持RSA

• paySign签名

paySign生成规则、响应详情请参见小程序调起支付API接口文档

3.3.2.3.【服务端】接收支付结果通知

步骤说明当用户完成支付微信会把相关支付结果将通过异步回调的方式通知商户商户需要接收处理并按文档规范返回应答

注意

  • 支付结果通知是以POST 方法访问商户设置的通知url通知的数据以JSON 格式通过请求主体BODY传输。通知的数据包括了加密的支付结果详情

  • 加密不能保证通知请求来自微信。微信会对发送给商户的通知进行签名并将签名值放在通知的HTTP头Wechatpay-Signature。商户应当验证签名以确认请求来自微信而不是其他的第三方。签名验证的算法请参考 《微信支付API v3签名验证》

  • 支付通知http应答码为200或204才会当作正常接收当回调处理异常时应答的HTTP状态码应为500或者4xx

  • 商户成功接收到回调通知后应返回成功的http应答码为200或204

  • 同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是当商户系统收到通知进行处理时先检查对应业务数据的状态并判断该通知是否已经处理。如果未处理则再进行处理如果已处理则直接返回结果成功。在对业务数据进行状态检查和处理之前要采用数据锁进行并发控制以避免函数重入造成的数据混乱

  • 对后台通知交互时如果微信收到商户的应答不符合规范或超时微信认为通知失败微信会通过一定的策略定期重新发起通知尽可能提高通知的成功率但微信不保证通知最终能成功。通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序支付通知API接口文档

3.3.2.4. 【服务端】查询订单

步骤说明当商户后台、网络、服务器等出现异常商户系统最终未接收到支付通知时商户可通过查询订单接口核实订单支付状态

示例代码(通过微信订单号查询)

PHP

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/pay/transactions/id/1217752501201407033233368018?mchid=1230000109', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
} catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}

注意

  • 查询订单可通过微信支付订单号商户订单号两种方式查询两种查询方式返回结果相同

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序查询订单API接口文档

3.3.2.5. 【服务端】关闭订单

步骤说明当商户订单支付失败需要生成新单号重新发起支付要对原订单号调用关单避免重复支付系统下单后用户支付超时系统退出不再受理避免用户继续请调用关单接口

示例代码

PHP

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no}/close', //请求URL
        [
            // JSON请求体'json' => [
                "mchid " => "1230000109",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
  } catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
  }
  

注意

  • 订单生成后不能马上调用关单接口最短调用时间间隔为5分钟

  • 已支付成功的订单不能关闭

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序接口文档

3.3.2.6. 【服务端】申请交易账单

步骤说明微信支付按天提供交易账单文件商户可以通过该接口获取账单文件的下载地址

示例代码

PHP

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/bill/tradebill?bill_date=2019-06-11&bill_type=ALL', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
} catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

注意

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序接口文档

3.3.2.7. 【服务端】下载账单

步骤说明通过申请交易账单接口获取到账单下载地址download_url后再通过该接口获取到对应的账单文件文件内包含交易相关的金额、时间、营销等信息供商户核对订单、退款、银行到账等情况

示例代码

PHP

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/billdownload/file?token=xx', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功echo"success,return body = " . $resp->getBody()->getContents()."\n";
    } elseif ($statusCode == 204) { //处理成功无返回Bodyecho"success";
    }
} catch (RequestException $e) {
    // 进行错误处理echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo"failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}

注意

• 账单文件的下载地址的有效时间为30s

• 强烈建议商户将实际账单文件的哈希值和之前从接口获取到的哈希值进行比对以确认数据的完整性

更多参数、响应详情及错误码请参见 JSAPI / APP / H5 / Native / 小程序下载账单API接口文档

3.4. 常见问题

Q在小程序内通过外部H5页面调起支付报错

A目前在小程序内只支持小程序支付不支持H5或JSAPI支付

Q调起小程序支付报“商户号该产品权限未开通”

A请按以下几点进行排查

1请检查请求参数是否正确如请求参数中的APPID是否与小程序对应

2APPID对应的小程序是否有开通小程序支付功能权限状态是否正常可登录商户平台核实

3APPID与商户号是否存在绑定关系可登录商户平台核实

Q小程序开通微信支付有哪几种方式

A可通过以下两种方式开通:

1绑定已有公众号的微信支付耗时10分钟即可只需原有公众号开通微信支付小程序微信支付可以选择绑定原来的微信支付商户号即可开通成功

2新申请微信支付耗时需要1-5个工作日需要提交和申请小程序一样的资料进行审核审核通过后才能开通成功

  1. 支付API列表

模块名称

功能列表

描述

小程序支付

JSAPI下单

通过本接口提交微信支付小程序支付订单。

查询订单

通过此接口查询订单状态。

关闭订单

通过此接口关闭待支付订单。

小程序调起支付

通过小程序下单接口获取到发起支付的必要参数prepay_id可以按照接口定义中的规则调起小程序支付。

支付结果通知

微信支付通过支付通知接口将用户支付成功消息通知给商户。

申请退款

商户可以通过该接口将支付金额退还给买家。

查询单笔退款

提交退款申请后通过调用该接口查询退款状态 。

退款结果通知

微信支付通过退款通知接口将用户退款成功消息通知给商户。

申请交易账单

商户可以通过该接口获取交易账单文件的下载地址。

申请资金账单

商户可以通过该接口获取资金账单文件的下载地址。

下载账单

通过申请交易/资金账单获取到download_url在该接口获取到对应的账单。

七.服务端php下单以及回调操作流程案例

SDK下载链接: https://pan.baidu.com/s/1ggZuH306tEMPJlShui2F8A 提取码: g4th

支付流程如下:

1.前端拉起商品列表

用户登录app后,进入商品购买页面,前端请求app商品列表api接口获取商品列表信息并展示

2.下单

用户点击'购买'操作,发送给服务端一条当前商品信息,服务端保存该商品的相关订单数据,并返回给前端支付所需要的请求数据前端调用支付sdk发起支付请求
    /**
     * 支付下单
     * @param array $params 订单信息
     * @return array
     */
    public static function Pay($params)
    {
        //获取商品内部订单号
        $innerOno = self::genInnerOno(date("Y-m-d H:i:s"), $params['user_id'], $paymentType);
        //生成订单
        $order = new Order();
        $order->order_id = $innerOno;  // 内部订单号
        $order->type = $params['type'];  // 支付类型1 微信jsapi支付 2 微信H5支付4 微信app支付5 微信小程序支付7 微信native支付
        $order->product_name = $params['name'];  // 商品名称
        $order->number = $params['num'];  // 购买商品个数
        $order->price = $params['price'];  // 商品单价, 1个商品价格
        $order->total_price = $params['total_price'];  // 总的价格
        $order->pay_amount = $params['pay_amount'];  // 应付总额:  实际应该支付的价格= 总金额 - 优惠金额
        $order->count = $params['count'];  // 购买后得到商品对应的产品数量
        $order->status = 0;  // 状态:0 待支付     
        $order->user_id = $params['user_id'];  // 用户游戏ID
        $order->expired_at = $params['expired_at'];  // 过期时间
        $order->created_by = $params['created_by'];  // 创建者
        $order->updated_by = $params['updated_by'];  // 创建者
 
        $result = $order->save();
        if (!$result) {
            $errors = '';
            if ($order->hasErrors()) {
                $tmp = $order->getErrors();
                foreach ($tmp as $rows) {
                    foreach ($rows as $row) {
                        $errors .= $row . '<br/>';
                    }
                }
            }
            throw new \Exception($errors);
        }
        $orderId = $order->id;
        
        $title = $model->product_name;
        $title = replaceStr($title);
        $price = intval($model->pay_amount * 100);
        if (in_array($model->user_id, Yii::$app->params['pay_test_user_ids'])) {
            $price = 1;
            if ($model->trade_code == self::PAY_WAY_WECHAT_H5 || $model->trade_code == self::PAY_WAY_WECHAT_JSAPI || $model->trade_code == self::PAY_WAY_WECHAT_APPLET|| $model->trade_code == self::PAY_WAY_WECHAT_MIDAS) {
                $price = 1;
            }
        }
        //构建向微信支付发送的参数
        $data = [
            'inner_ono' => $model->deal_number,
            'title' => $title,
            'price' => $price,
            'body' => $title,
        ];
        $logDir = Yii::getAlias("@frontend/runtime/logs/wxpay");
        try {
            //引入上面下载的SDK中的付方法
            $pay = new Pay();
            if ($tradeType == self::PAY_WAY_WECHAT_APP) { //微信app支付
                $data = $pay->appPay($data);
                if (!$data) {
                    jsonFail();
                }
                $result['app_sign'] = $data;
            } elseif ($tradeType == self::PAY_WAY_WECHAT_JSAPI || $tradeType == self::PAY_WAY_WECHAT_APPLET) { //微信jsapi支付,微信小程序支付
                //获取用户微信open_id
                $user = GameUserReg::find()->select(['wx'])->where(['id' => $model->game_user_id])->asArray()->one();
                if (!$user) {
                    throw new \Exception('用户不存在');
                }
                if (!$user['wx']) {
                    throw new \Exception('open_id不能为空');
                }
                $data['open_id'] = $user['wx'];
                $data = $pay->jsApiPay($data);
                $result['jsapi_sign'] = $data;
            } elseif ($tradeType == self::PAY_WAY_WECHAT_H5) { //微信H5支付
                $data = $pay->h5Pay($data);
                $result['mweb_url'] = $data;
            } elseif ($tradeType == self::PAY_WAY_WECHAT_NATIVE) { //微信native支付
                $data = $pay->nativePay($data);
                $result['code_url'] = $data['code_url'];
            }
            $msg = "#{$model->created_by} 2nd. 统一下单 - end." . json_encode($data);
            fileLogByDir($msg, $logDir);
        } catch (\Exception $e) {
            $msg = 'error: ' . $e->getMessage() . ' (file: ' . $e->getFile() . ' [' . $e->getLine() . '])';
            fileLogByDir($msg, $logDir);
            throw $e;
        }

        return jsonSuccess($result);
    }
 
   /**
     * 生成本系统内部订单号, 在向第三方服务商发起支付时需要使用.
     *
     * 下单时的处理流程:
     *   1. 属性 ono 不要赋值, 成功插入(保存)订单.
     *   1. 支付前生成本系统内部订单号, 向第三方发起支付请求.
     *   1. 接收到支付成功回调通知时, 将第三方订单号保存到本次付款的订单的 ono 字段上.
     *
     * 格式: 下单时间+支付方式+ 4位数字修正值. 如 "20150930140041+1+1234".
     * 最大长度 32 个字符. 这也是 wx 可接受的订单号最大长度.
     *
     * @param int $createdAt 订单创建时间戳, 即 下单时间戳.
     * @param int $createdBy 订单创建人 ID, 即 下单会员 ID.
     * @return string
     * @throws \Exception
     */
 
    public static function genInnerOno($createdAt, $createdBy)
    {
        $createdAt = strtotime($createdAt);
        if (1 > $createdAt || 1 > $createdBy) {
            throw new \Exception('参数错误');
        }
 
        // 生成一个修正值, 一定程度上增加订单号的随机性.
        $tmp = intval(substr($createdAt, -4)) + intval(substr($createdBy, -2));
        if (4 < strlen($tmp)) {
            $tmp = substr($tmp, -4);
        }
 
        $tmp = date('YmdHis', $createdAt) . $tmp . rand(100, 900);
        return $tmp;
    }

3. 支付

前端获取服务端返回的支付所需要的请求数据后拼接支付请求参数调用支付sdk拉起微信发起支付请求

4. 回调操作

前端支付成功后微信服务器会请求业务服务端的回调方法对支付订单进行校验验签操作根据验签结果处理订单业务逻辑
php以yii2框架为参考
    /**
     * 支付回调
     */
    public function actionNotify()
    {
        $input_data = file_get_contents('php://input');
        //转换通知的JSON文本消息为PHP Array数组
        $inBodyArray = json_decode($input_data, true);

          //判断通知请求
        $trans = Yii::$app->db->beginTransaction();
        if ($inBodyArray['event_type'] == "TRANSACTION.SUCCESS") {  //通知的类型支付成功通知的类型为TRANSACTION.SUCCESS
            try {
                if ($inBodyArray['resource_type'] == "encrypt-resource") {   //通知的资源数据类型
                    //获取resource通知资源数据(json格式)
                    $nonce = $inBodyArray['resource']['nonce'];
                    $aad = $inBodyArray['resource']['associated_data'];
                    $text = $inBodyArray['resource']['ciphertext'];
                    //商户平台设置的api v3 密码
                    $key = Yii::$app->params['wx']['api_v3_key'];
                    // 解密ciphertext文本消息
                    $inBodyResource = AesGcm::decrypt($text, $key, $nonce, $aad);
                    // 把解密后的文本转换为PHP Array数组
                    $inBodyResourceArray = ArrayHelper::toArray(json_decode($inBodyResource, true));
                    //判断交易状态
                    $trade_state = $inBodyResourceArray['trade_state'];
                    if ($trade_state != 'SUCCESS') {
                        throw new \Exception($inBodyResourceArray['trade_state_desc']);
                    }
                    // 处理业务逻辑
                    $ono = $inBodyResourceArray["transaction_id"];
                    $innerOno = $inBodyResourceArray['out_trade_no'];
                    // 订单状态
                    $status = UserOrder::STATUS_BUY;

                    //交易类型
                    $trade_type = $inBodyResourceArray['trade_type'];
                    if ($trade_type == 'JSAPI') {
                        $trade_code = UserOrder::PAY_WAY_WECHAT_JSAPI;
                    } elseif ($trade_type == 'NATIVE') {
                        $trade_code = UserOrder::PAY_WAY_WECHAT_NATIVE;
                    } elseif ($trade_type == 'APP') {
                        $trade_code = UserOrder::PAY_WAY_WECHAT_APP;
                    } elseif ($trade_type == 'MWEB') {
                        $trade_code = UserOrder::PAY_WAY_WECHAT_H5;
                    } else {
                        $trade_code = null;
                    }
                        // 变更订单属性
                        Order::changeAttribute(
                            ['inner_ono' => $innerOno],
                            [
                                'status' => $status,
                                'paid_at' => time(),
                                'ono' => $ono,
                                'trade_code' => $trade_code,
                            ]
                        );
                        // 变更订单商品状态
                        OrderWare::changeStatus($status, ['inner_ono' => $innerOno]);
                   

                    $trans->commit();
                    $msg = '支付成功后回调: ' . $ono . '订单更新成功';
                    fileLogByDir($msg, $logDir);
                    return json_encode[
                        "code" => "SUCCESS",
                        "message" => ""
                    ]);
                }
            } catch (\Exception $e) {
                $msg = 'error: ' . $e->getMessage() . ' (file: ' . $e->getFile() . ' [' . $e->getLine() . '])';
                fileLogByDir($msg, $logDir);
                $trans->rollBack();
            }
        }

        return json_encode([
            "code" => "ERROR",
            "message" => "失败"
        ]);
    }

5.上面需要使用到的公共方法

/**
 * 操作成功
 * @example1 jsonSuccess();
 */
function jsonSuccess($data = NULL, $message = '操作成功')
{
    header("Content-Type:application/json");
    $json = array();
    $json['code'] = 0;
    $json['data'] = $data;
    $json['message'] = $message;
    $json['request_time'] = now();
    echo Json::encode($json);
    exit();
}

/**
 * 错误信息
 * @example1 jsonFail();
 * @example1 jsonFail("删除失败");
 * @example2 jsonFail($model->getErrors());
 */
function jsonFail($message = '请求失败', $code = 1, $data = null)
{
    header("Content-Type:application/json");
    $json = array();
    $json['code'] = $code;
    $json['data'] = $data;
    $json['message'] = $message;
    $json['request_time'] = now();
    echo Json::encode($json);
    exit();
}

/**
 * 过滤掉特殊的字符
 * @param $str
 * @param string $replacement
 * @return string|string[]|null
 */
function replaceStr($str, $replacement = '')
{
    $regex = "/\/|\|\|\。|\|\|\“|\”|\【|\】|\『|\』|\|\|\《|\》|\’|\‘|\ |\·|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\+|\{|\}|\:|\<|\>|\?|\[|\]|\,|\.|\/|\;|\'|\`|\-|\=|\\\|\|/";
    $result = preg_replace($regex, $replacement, $str);

    return $result;
}
Yii2 支付宝相关配置params-local.php
<?php

return [
      // 微信支付配置
    'wx' => [
        //应用ID,您的APPID。
        'app_id' => "xxx",
        //小程序应用ID
        'applet_id' => 'xxx',
        //小程序应用秘钥
        'applet_secret' => 'xxx',
        //小程序消息通知token
        'token' => 'xxx',
        //小程序消息通知 消息加密密钥
        'encodingAESKey' => 'xxx',
        //公众平台的appId
        'app_id_public' => 'xxx',
        'app_id_secret' => 'xxx',

        //商户私钥您的原始格式RSA私钥
        'merchant_id' => "xxx",
        //异步通知地址
        'notify_url' => "http://xxx.com/wechat-notify",
        // 正式环境支付网关
        'gateway_url' => "",    //https://api.mch.weixin.qq.com/pay/unifiedorder
        //商户API证书序列号
        'serial_number' => "xxx",
        //同步跳转
        'return_url' => "",
        //编码格式
        'charset' => "UTF-8",
        //签名方式
        'sign_type' => "MD5",
        //KEY商户支付密钥,设置地址:https://pay.weixin.qq.com/index.php/account/api_cert
        'key' => "xxx",
        //V3秘钥
        'api_v3_key' => "xxx",
        'pay_test' => 1, //是否支付测试
        'is_screen_pay' => 1, //是否屏蔽支付
    ],
];

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

“微信支付,JSAPI支付,APP支付,H5支付,Native支付,小程序支付功能详情以及回调处理” 的相关文章