视频一区二区三区自拍_千金肉奴隷1985未删减版在线观看_国产成人黄色视频在线播放_少女免费播放片高清在线观看_国产精品v欧美精品v

商戶(hù)進(jìn)件
特約商戶(hù)進(jìn)件
基礎(chǔ)支付
JSAPI支付
APP支付
H5支付
Native支付
小程序支付
合單支付
付款碼支付
經(jīng)營(yíng)能力
支付即服務(wù)
點(diǎn)金計(jì)劃
行業(yè)方案
平臺(tái)收付通
智慧商圈
微信支付分停車(chē)服務(wù)
電子發(fā)票
營(yíng)銷(xiāo)工具
代金券
商家券
委托營(yíng)銷(xiāo)
支付有禮
小程序發(fā)券插件
H5發(fā)券
圖片上傳(營(yíng)銷(xiāo)專(zhuān)用)
現(xiàn)金紅包
資金應(yīng)用
分賬
連鎖品牌分賬
風(fēng)險(xiǎn)合規(guī)
商戶(hù)開(kāi)戶(hù)意愿確認(rèn)
消費(fèi)者投訴2.0
商戶(hù)平臺(tái)處置通知
其他能力
圖片上傳
視頻上傳
微信支付平臺(tái)證書(shū)

合單支付開(kāi)發(fā)指引

1. 接口規(guī)則

為了在保證支付安全的前提下,帶給商戶(hù)簡(jiǎn)單、一致且易用的開(kāi)發(fā)體驗(yàn),我們推出了全新的微信支付APIv3接口。該版本API的具體規(guī)則請(qǐng)參考“APIv3接口規(guī)則

2. 開(kāi)發(fā)準(zhǔn)備

2.1. 搭建和配置開(kāi)發(fā)環(huán)境

為了幫助開(kāi)發(fā)者調(diào)用開(kāi)放接口,我們提供了JAVA、PHP、GO三種語(yǔ)言版本的開(kāi)發(fā)庫(kù),封裝了簽名生成、簽名驗(yàn)證、敏感信息加/解密、媒體文件上傳等基礎(chǔ)功能(更多語(yǔ)言版本的開(kāi)發(fā)庫(kù)將在近期陸續(xù)提供

測(cè)試步驟

1、根據(jù)自身開(kāi)發(fā)語(yǔ)言,選擇對(duì)應(yīng)的開(kāi)發(fā)庫(kù)并構(gòu)建項(xiàng)目,具體配置請(qǐng)參考下面鏈接的詳細(xì)說(shuō)明:

    ? wechatpay-java(推薦)wechatpay-apache-httpclient,適用于Java開(kāi)發(fā)者。

    ? wechatpay-php(推薦)、wechatpay-guzzle-middleware,適用于PHP開(kāi)發(fā)者

    注:當(dāng)前開(kāi)發(fā)指引接口PHP示例代碼采用wechatpay-guzzle-middleware版本

    ? wechatpay-go,適用于Go開(kāi)發(fā)者

更多資源可前往微信支付開(kāi)發(fā)者社區(qū)搜索查看

2、創(chuàng)建加載商戶(hù)私鑰、加載平臺(tái)證書(shū)、初始化httpClient的通用方法


@Before
public void setup() throws IOException {
    // 加載商戶(hù)私鑰(privateKey:私鑰字符串)
    PrivateKey merchantPrivateKey = PemUtil
            .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
 
    // 加載平臺(tái)證書(shū)(mchId:商戶(hù)號(hào),mchSerialNo:商戶(hù)證書(shū)序列號(hào),apiV3Key:V3密鑰)
    AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
            new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
 
    // 初始化httpClient
    httpClient = WechatPayHttpClientBuilder.create()
            .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
            .withValidator(new WechatPay2Validator(verifier)).build();
}
 
@After
public void after() throws IOException {
    httpClient.close();
}

use GuzzleHttp\Exception\RequestException;
use WechatPay\GuzzleMiddleware\WechatPayMiddleware;
use WechatPay\GuzzleMiddleware\Util\PemUtil;
use GuzzleHttp\HandlerStack;
 
// 商戶(hù)相關(guān)配置,
$merchantId = '1000100'; // 商戶(hù)號(hào)
$merchantSerialNumber = 'XXXXXXXXXX'; // 商戶(hù)API證書(shū)序列號(hào)
$merchantPrivateKey = PemUtil::loadPrivateKey('./path/to/mch/private/key.pem'); // 商戶(hù)私鑰文件路徑
 
// 微信支付平臺(tái)配置
$wechatpayCertificate = PemUtil::loadCertificate('./path/to/wechatpay/cert.pem'); // 微信支付平臺(tái)證書(shū)文件路徑
 
// 構(gòu)造一個(gè)WechatPayMiddleware
$wechatpayMiddleware = WechatPayMiddleware::builder()
    ->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 傳入商戶(hù)相關(guān)配置
    ->withWechatPay([ $wechatpayCertificate ]) // 可傳入多個(gè)微信支付平臺(tái)證書(shū),參數(shù)類(lèi)型為array
    ->build();
 
// 將WechatPayMiddleware添加到Guzzle的HandlerStack中
$stack = GuzzleHttp\HandlerStack::create();
$stack->push($wechatpayMiddleware, 'wechatpay');
 
// 創(chuàng)建Guzzle HTTP Client時(shí),將HandlerStack傳入,接下來(lái),正常使用Guzzle發(fā)起API請(qǐng)求,WechatPayMiddleware會(huì)自動(dòng)地處理簽名和驗(yàn)簽
$client = new GuzzleHttp\Client(['handler' => $stack]);

/*
    Package core 微信支付api v3 go http-client 基礎(chǔ)庫(kù),你可以使用它來(lái)創(chuàng)建一個(gè)client,并向微信支付發(fā)送http請(qǐng)求
    只需要你在初始化客戶(hù)端的時(shí)候,傳遞credential以及validator
    credential用來(lái)生成http header中的authorization信息
    validator則用來(lái)校驗(yàn)回包是否被篡改
    如果http請(qǐng)求返回的err為nil,一般response.Body 都不為空,你可以嘗試對(duì)其進(jìn)行序列化
    請(qǐng)注意及時(shí)關(guān)閉response.Body
    注意:使用微信支付apiv3 go庫(kù)需要引入相關(guān)的包,該示例代碼必須引入的包名有以下信息

    "context"
    "crypto/x509"
    "fmt"
    "io/ioutil"
    "log"
    "github.com/wechatpay-apiv3/wechatpay-go/core"
    "github.com/wechatpay-apiv3/wechatpay-go/core/option"
    "github.com/wechatpay-apiv3/wechatpay-go/utils"

    */
func SetUp() (opt []option.ClientOption, err error) {
    //商戶(hù)號(hào)
    mchID := ""
    //商戶(hù)證書(shū)序列號(hào)
    mchCertSerialNumber := ""
    //商戶(hù)私鑰文件路徑
    privateKeyPath := ""
    //平臺(tái)證書(shū)文件路徑
    wechatCertificatePath := ""

    // 加載商戶(hù)私鑰
    privateKey, err := utils.LoadPrivateKeyWithPath(privateKeyPath)
    if err != nil {
        log.Printf("load private err:%s", err.Error())
        return nil, err
    }
    // 加載微信支付平臺(tái)證書(shū)
    wechatPayCertificate, err := utils.LoadCertificateWithPath(wechatCertificatePath)
    if err != nil {
        log.Printf("load certificate err:%s",err)
        return nil, err
    }
    //設(shè)置header頭中authorization信息
    opts := []option.ClientOption{
        option.WithMerchant(mchID, mchCertSerialNumber, privateKey), // 設(shè)置商戶(hù)相關(guān)配置
        option.WithWechatPay([]*x509.Certificate{wechatPayCertificate}), // 設(shè)置微信支付平臺(tái)證書(shū),用于校驗(yàn)回包信息用
    }
    return opts, nil
}

3、基于接口的示例代碼,替換請(qǐng)求參數(shù)后可發(fā)起測(cè)試

說(shuō)明:

? 上面的開(kāi)發(fā)庫(kù)為微信支付官方開(kāi)發(fā)庫(kù),其它沒(méi)有審核或者控制下的第三方工具和庫(kù),微信支付不保證它們的安全性和可靠性

通過(guò)包管理工具引入SDK后,可根據(jù)下面每個(gè)接口的示例代碼替換相關(guān)參數(shù)后進(jìn)行快速測(cè)試

? 開(kāi)發(fā)者如果想詳細(xì)了解簽名生成、簽名驗(yàn)證、敏感信息加/解密、媒體文件上傳等常用方法的具體代碼實(shí)現(xiàn),可閱讀下面的詳細(xì)說(shuō)明:

    1.簽名生成

    2.簽名驗(yàn)證

    3.敏感信息加解密

    4.merchantPrivateKey(私鑰)

    5.wechatpayCertificates(平臺(tái)證書(shū))

    6.APIV3Key(V3 key)

? 如想更詳細(xì)的了解我們的接口規(guī)則,可查看我們的接口規(guī)則指引文檔

2.2. 業(yè)務(wù)開(kāi)發(fā)配置

合單支付目前支持在微信外H5、APP、JSAPI、小程序、Native掃碼5個(gè)場(chǎng)景使用,下面依次為你介紹這5個(gè)場(chǎng)景需求進(jìn)行的業(yè)務(wù)開(kāi)發(fā)配置

2.2.1. 微信外H5場(chǎng)景開(kāi)發(fā)配置:

開(kāi)通H5支付權(quán)限:前往【微信支付商戶(hù)平臺(tái)—>產(chǎn)品中心—>H5支付—>申請(qǐng)開(kāi)通】

設(shè)置H5支付域名:登錄【微信支付商戶(hù)平臺(tái)—>產(chǎn)品中心—>開(kāi)發(fā)配置—>H5支付】,設(shè)置后一般10分鐘內(nèi)生效。

注意

      ? 域名必須通過(guò)ICP備案

      ? 域名填寫(xiě)格式不包含http://或https://

2.2.2. APP場(chǎng)景開(kāi)發(fā)配置

一、注冊(cè)APP

APP接入微信支付,需要先將商戶(hù)APP在微信開(kāi)放平臺(tái)進(jìn)行注冊(cè),登記APP開(kāi)發(fā)參數(shù)以生成APPID。具體操作步驟如下:

1. 登錄微信開(kāi)放平臺(tái),進(jìn)入【管理中心 → 移動(dòng)應(yīng)用 → 創(chuàng)建移動(dòng)應(yīng)用】;

2. 完成基本信息的錄入,商戶(hù)需要在本步驟提交APP對(duì)應(yīng)的下載地址,應(yīng)用官網(wǎng),應(yīng)用水印,icon等業(yè)務(wù)信息;

3. 完成平臺(tái)信息的錄入,商戶(hù)需要在本步驟提交APP在Android及iOS端對(duì)應(yīng)的開(kāi)發(fā)參數(shù),包括Android端應(yīng)用的包名,應(yīng)用簽名,iOS端應(yīng)用的bundle ID, universal link等;

注意

      ? Android應(yīng)用包名和簽名的相關(guān)說(shuō)明,請(qǐng)參考Android開(kāi)發(fā)要點(diǎn)說(shuō)明

4. 以上信息全部提交完成后,即完成APP的注冊(cè),商戶(hù)可在【管理中心 → 移動(dòng)應(yīng)用】中,選擇具體的應(yīng)用查看其APPID及已獲得的接口能力;

5. 獲取到APP的APPID后,需要將該APPID與商戶(hù)的收款mchid進(jìn)行綁定,商戶(hù)可登錄商戶(hù)平臺(tái)后前往【產(chǎn)品中心 -> AppID賬號(hào)管理】界面中進(jìn)行AppID的綁定及管理,界面如圖所示:

二、iOS開(kāi)發(fā)要點(diǎn)說(shuō)明:

? iOS系統(tǒng)opensdk升級(jí)指引:

由于蘋(píng)果公司在iOS13系統(tǒng)回收了查詢(xún) App bundleID 的能力,導(dǎo)致微信無(wú)法保證授權(quán)憑證能正確返回給AppID對(duì)應(yīng)的應(yīng)用。為此,微信支付強(qiáng)烈要求所有商戶(hù)盡快升級(jí)到OpenSDK1.8.6,并讓用戶(hù)及時(shí)更新APP,否則安全風(fēng)險(xiǎn)將一直存在。謝謝配合!

詳細(xì)OpenSDK升級(jí)指引請(qǐng)參見(jiàn):opensdk升級(jí)指引

注意:opensdk升級(jí)后請(qǐng)一定按照文檔要求完成驗(yàn)證工作,確保opensddk升級(jí)成功。

? 開(kāi)發(fā)配置:

以下項(xiàng)目開(kāi)發(fā)環(huán)境以Xcode6.0,運(yùn)行環(huán)境為IOS7.0為例,說(shuō)明其開(kāi)發(fā)中需要的操作。

1. 項(xiàng)目設(shè)置APPID

商戶(hù)在微信開(kāi)放平臺(tái)申請(qǐng)開(kāi)發(fā)APP應(yīng)用后,微信開(kāi)放平臺(tái)會(huì)生成APP的唯一標(biāo)識(shí)APPID。在Xcode中打開(kāi)項(xiàng)目,設(shè)置項(xiàng)目屬性中的URL Schemes為您的APPID。如圖8.7標(biāo)紅位置所示。

2. 注冊(cè)APPID

商戶(hù)APP工程中引入微信lib庫(kù)和頭文件,調(diào)用API前,需要先向微信注冊(cè)您的APPID,代碼如下:

[WXApi registerApp:@"wxd930ea5d5a258f4f" withDescription:@"demo 2.0"];

注意:

? OpenSDK前端拉起支付及SDK回調(diào)的相關(guān)說(shuō)明,請(qǐng)參考【客戶(hù)端】APP調(diào)起支付

三、Android開(kāi)發(fā)要點(diǎn)說(shuō)明:

1. 后臺(tái)設(shè)置:

商戶(hù)在微信開(kāi)放平臺(tái)申請(qǐng)開(kāi)發(fā)應(yīng)用后,微信開(kāi)放平臺(tái)會(huì)生成APP的唯一標(biāo)識(shí)APPID。由于需要保證支付安全,需要在開(kāi)放平臺(tái)綁定商戶(hù)應(yīng)用包名和應(yīng)用簽名,設(shè)置好后才能正常發(fā)起支付。設(shè)置界面在【開(kāi)放平臺(tái)】中的欄目【管理中心 / 修改應(yīng)用 / 修改開(kāi)發(fā)信息】里面,如圖紅框內(nèi)所示。

應(yīng)用包名:是在APP項(xiàng)目配置文件AndroidManifest.xml中聲明的package值,例如圖中的package="demo.wxpay.tenpay.com"。

應(yīng)用簽名:根據(jù)項(xiàng)目的應(yīng)用包名和編譯使用的keystore,可由簽名工具生成一個(gè)32位的md5串,在調(diào)試的手機(jī)上安裝簽名工具后,運(yùn)行可生成應(yīng)用簽名串,如圖8.9所示,綠色串即應(yīng)用簽名。簽名工具下載地址

2. 注冊(cè)APPID

商戶(hù)APP工程中引入微信JAR包,調(diào)用API前,需要先向微信注冊(cè)您的APPID,代碼如下:

final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);

// 將該app注冊(cè)到微信

msgApi.registerApp("wxd930ea5d5a258f4f");

2.2.3. JSAPI場(chǎng)景開(kāi)發(fā)配置:

設(shè)置支付目錄

    ? 支付授權(quán)目錄說(shuō)明:

1、商戶(hù)最后請(qǐng)求拉起微信支付收銀臺(tái)的頁(yè)面地址我們稱(chēng)之為“支付目錄”,例如:https://www.weixin.com/pay.php。

2、商戶(hù)實(shí)際的支付目錄必須和在微信支付商戶(hù)平臺(tái)設(shè)置的一致,否則會(huì)報(bào)錯(cuò)“當(dāng)前頁(yè)面的URL未注冊(cè):”

    ? 支付授權(quán)目錄設(shè)置說(shuō)明:【登錄微信支付商戶(hù)平臺(tái)->產(chǎn)品中心->開(kāi)發(fā)配置】,設(shè)置后一般5分鐘內(nèi)生效。(配置頁(yè)見(jiàn)下圖)

    ? 支付授權(quán)目錄校驗(yàn)規(guī)則說(shuō)明:

1、如果支付授權(quán)目錄設(shè)置為頂級(jí)域名(例如:https://www.weixin.com/),那么只校驗(yàn)頂級(jí)域名,不校驗(yàn)后綴;

2、如果支付授權(quán)目錄設(shè)置為多級(jí)目錄,就會(huì)進(jìn)行全匹配,例如設(shè)置支付授權(quán)目錄為https://www.weixin.com/abc/123/,則實(shí)際請(qǐng)求頁(yè)面目錄不能為https://www.weixin.com/abc/,也不能為https://www.weixin.com/abc/123/pay/,必須為https://www.weixin.com/abc/123/

設(shè)置授權(quán)域名

授權(quán)域名說(shuō)明:開(kāi)發(fā)JSAPI支付時(shí),在JSAPI下單接口中要求必傳用戶(hù)openid,而獲取openid則需要您在公眾平臺(tái)設(shè)置獲取openid的域名,只有被設(shè)置過(guò)的域名才是一個(gè)有效的獲取openid的域名,否則將獲取失敗。具體配置頁(yè)見(jiàn)下圖

授權(quán)域名設(shè)置說(shuō)明:登錄【微信公眾平臺(tái)-->公眾號(hào)設(shè)置】

2.2.4. 小程序場(chǎng)景開(kāi)發(fā)配置:

賬號(hào)申請(qǐng)指引:

a、小程序開(kāi)通微信支付,即申請(qǐng)或復(fù)用微信支付商戶(hù)號(hào) 申請(qǐng)完小程序后,登錄小程序后臺(tái)。點(diǎn)擊左側(cè)導(dǎo)航欄的微信支付,在頁(yè)面中進(jìn)行開(kāi)通。(開(kāi)通申請(qǐng)要求小程序已發(fā)布上線)

b、點(diǎn)擊開(kāi)通按鈕后,有2種方式可以獲取微信支付能力,新申請(qǐng)微信支付商戶(hù)號(hào)或綁定一個(gè)已有的微信支付商戶(hù)號(hào),請(qǐng)根據(jù)你的業(yè)務(wù)需要和具體情況選擇,只能二選一。詳見(jiàn)微信支付商戶(hù)接入指引

服務(wù)器配置要求:

a、小程序訪問(wèn)商戶(hù)服務(wù)都是通過(guò)HTTPS,開(kāi)發(fā)部署的時(shí)候需要HTTPS服務(wù)器

b、服務(wù)器域名配置

①、每個(gè)微信小程序需要事先設(shè)置通訊域名,小程序只可以跟指定的域名進(jìn)行網(wǎng)絡(luò)通信。包括普通 HTTPS 請(qǐng)求(wx.request)、上傳文件(wx.uploadFile)、下載文件(wx.downloadFile)和 WebSocket 通信(wx.connectSocket)

②、從基礎(chǔ)庫(kù) 2.4.0 開(kāi)始,網(wǎng)絡(luò)接口允許與局域網(wǎng) IP 通信,但要注意 不允許與本機(jī) IP 通信

注意:

    ? 域名只支持 https (wx.request、wx.uploadFile、wx.downloadFile) 和 wss (wx.connectSocket) 協(xié)議

    ? 域名不能使用 IP 地址(小程序的局域網(wǎng) IP 除外)或 localhost

    ? 可以配置端口,如https://myserver.com:8080,但是配置后只能向https://myserver.com:8080 發(fā)起請(qǐng)求。如果向https://myserver.com、https://myserver.com:9091等 URL 請(qǐng)求則會(huì)失敗

    ? 如果不配置端口。如 https://myserver.com,那么請(qǐng)求的 URL 中也不能包含端口,甚至是默認(rèn)的 443 端口也不可以。如果向https://myserver.com:443請(qǐng)求則會(huì)失敗

    ? 域名必須經(jīng)過(guò) ICP 備案

    ? 出于安全考慮,api.weixin.qq.com不能被配置為服務(wù)器域名,相關(guān)API也不能在小程序內(nèi)調(diào)用。 開(kāi)發(fā)者應(yīng)將 AppSecret 保存到后臺(tái)服務(wù)器中,通過(guò)服務(wù)器使用 getAccessToken 接口獲取 access_token,并調(diào)用相關(guān) API

    ? 不支持配置父域名,使用子域名

    ? 可查閱小程序網(wǎng)絡(luò)請(qǐng)求以了解更多信息

2.2.5. Native掃碼場(chǎng)景開(kāi)發(fā)配置:

暫無(wú)需特殊配置內(nèi)容

3. 快速接入

3.1. 業(yè)務(wù)流程圖

重要步驟說(shuō)明:

步驟一: 用戶(hù)在商戶(hù)側(cè)發(fā)起支付請(qǐng)求,商戶(hù)先通過(guò)后臺(tái)接口-合單下單接口創(chuàng)建合單支付訂單。

步驟二: 商戶(hù)再根據(jù)用戶(hù)發(fā)起支付請(qǐng)求的具體場(chǎng)景通過(guò)H5/小程序/APP/公眾號(hào)頁(yè)面調(diào)起微信支付收銀臺(tái),完成支付請(qǐng)求。

步驟三: 用戶(hù)支付成功后,商戶(hù)可接收到支付結(jié)果回調(diào)通知

步驟四: 如果商戶(hù)長(zhǎng)時(shí)間未收到回調(diào)通知,可通過(guò)合單查詢(xún)訂單接口主動(dòng)查詢(xún)訂單支付狀態(tài)。

3.2. API接入(含示例代碼)

本文檔展示了如何使用微信支付服務(wù)端 SDK 快速接入合單支付產(chǎn)品,完成與微信支付對(duì)接的部分。

注意

  • 文檔中的代碼示例是用來(lái)闡述 API 基本使用方法,代碼中的示例參數(shù)需替換成商戶(hù)自己賬號(hào)及請(qǐng)求參數(shù)才能跑通。
  • 以下接入步驟僅提供參考,請(qǐng)商戶(hù)結(jié)合自身業(yè)務(wù)需求進(jìn)行評(píng)估、修改。
3.2.1.【服務(wù)端】合單下單

步驟說(shuō)明:用戶(hù)在商戶(hù)側(cè)選擇商品下單購(gòu)買(mǎi)時(shí),商戶(hù)系統(tǒng)先調(diào)用該接口在微信支付服務(wù)后臺(tái)生成預(yù)支付交易單,然后使用我們提供的客戶(hù)端方法(下文介紹)調(diào)起微信支付收銀臺(tái),即可完成支付。

合單下單接口為了區(qū)分用戶(hù)發(fā)起支付的5個(gè)場(chǎng)景:微信外H5、APP、JSAPI、小程序、Native掃碼,我們分別使用了4個(gè)不同接口地址對(duì)應(yīng)這5個(gè)場(chǎng)景(小程序與公眾號(hào)合單下單接口地址相同):

https://api.mch.weixin.qq.com/v3/combine-transactions/h5——微信外H5場(chǎng)景合單下單接口地址

https://api.mch.weixin.qq.com/v3/combine-transactions/app——APP場(chǎng)景合單下單接口地址

https://api.mch.weixin.qq.com/v3/combine-transactions/jsapi——JSAPI、小程序場(chǎng)景合單下單接口地址

https://api.mch.weixin.qq.com/v3/combine-transactions/native——Native掃碼場(chǎng)景合單下單接口地址

下面以JSAPI、小程序場(chǎng)景為例,為你展示基礎(chǔ)下單接口的請(qǐng)求示例。

示例代碼


public void CombineJsapiPrepay() throws Exception{

  //請(qǐng)求URL
  HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/combine-transactions/jsapi");
  // 請(qǐng)求body參數(shù)
  String reqdata = "{"
          + "\"combine_out_trade_no\":\"1217752501201407033233368018\","
          + "\"combine_mchid\":\"1230000109\","
          + "\"combine_appid\":\"wxd678efh567hg6787\","
          + "\"scene_info\": {"
          + "\"device_id\":\"POS1:1\","
          + "\"payer_client_ip\":\"14.17.22.32\""
          + "},"
          + "\"sub_orders\": ["
          + "{"
          + "\"mchid\":\"1230000109\","
          + "\"attach\":\"深圳分店\","
          + "\"amount\": {"
          + "\"total_amount\":10,"
          + "\"currency\":\"CNY\""
          + "},"
          + "\"out_trade_no\":\"20150806125346\","
          + "\"sub_mchid\":\"1900000109\","
          + "\"description\":\"騰訊充值中心-QQ會(huì)員充值\""
          + "}"
          + "],"
          + "\"combine_payer_info\": {"
          + "\"openid\":\"oUpF8uMuAJO_M2pxb1Q9zNjWeS6o\""
          + "},"
          + "\"time_start\":\"2018-06-08T10:34:56+08:00\","
          + "\"time_expire\":\"2018-06-08T10:34:56+08:00\","
          + "\"notify_url\":\"https://yourapp.com/notify\""
          + "}";
  StringEntity entity = new StringEntity(reqdata,"utf-8");
  entity.setContentType("application/json");
  httpPost.setEntity(entity);
  httpPost.setHeader("Accept", "application/json");

  //完成簽名并執(zhí)行請(qǐng)求
  CloseableHttpResponse response = httpClient.execute(httpPost);

  try {
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode == 200) { //處理成功
          System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
      } else if (statusCode == 204) { //處理成功,無(wú)返回Body
          System.out.println("success");
      } else {
          System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
          throw new IOException("request failed");
      }
  } finally {
      response.close();
  }
}
                      

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/combine-transactions/jsapi', //請(qǐng)求URL
        [
            // JSON請(qǐng)求體
            'json' => [
                "combine_out_trade_no" => "1217752501201407033233368018",
                "combine_mchid" => "1230000109",
                "combine_appid" => "wxd678efh567hg6787",
                "scene_info" => [
                    "device_id" => "POS1:1",
                    "payer_client_ip" => "14.17.22.32",
                ],
                "sub_orders" => [
                    [
                        "mchid" => "1230000109",
                        "attach" => "深圳分店",
                        "amount" => [
                            "total_amount" => 10,
                            "currency" => "CNY",
                        ],
                        "out_trade_no" => "20150806125346",
                        "sub_mchid" => "1900000109",
                        "description" => "騰訊充值中心-QQ會(huì)員充值",
                    ],
                ],
                "combine_payer_info" => [
                    "openid" => "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o",
                ],
                "time_start" => "2018-06-08T10:34:56+08:00",
                "time_expire" => "2018-06-08T10:34:56+08:00",
                "notify_url" => "https://yourapp.com/notify",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //處理成功
        echo "success,return body = " . $resp->getReasonPhrase()."\n";
    } else if ($statusCode == 204) { //處理成功,無(wú)返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 進(jìn)行錯(cuò)誤處理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}

重要入?yún)⒄f(shuō)明:

? out_trade_no:商戶(hù)系統(tǒng)內(nèi)部訂單號(hào),只能是數(shù)字、大小寫(xiě)字母_-*且在同一個(gè)商戶(hù)號(hào)下唯一

? description:商品描述

? notify_url:支付回調(diào)通知URL,該地址必須為直接可訪問(wèn)的URL,不允許攜帶查詢(xún)串

? total:訂單總金額,單位為分

? openid:openid是微信用戶(hù)在appid下的唯一用戶(hù)標(biāo)識(shí)(appid不同,則獲取到的openid就不同),可用于永久標(biāo)記一個(gè)用戶(hù)。openid獲取方式請(qǐng)參考以下文檔小程序獲取openid公眾號(hào)獲取openidAPP獲取openid

更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn) 合單JSAPI下單

3.2.2.【客戶(hù)端】JSAPI調(diào)起支付

步驟說(shuō)明:通過(guò)合單下單API成功獲取預(yù)支付交易會(huì)話(huà)標(biāo)識(shí)(prepay_id)后,需要通過(guò)JSAPI調(diào)起支付API來(lái)調(diào)起微信支付收銀臺(tái)

注意

  • WeixinJSBridge內(nèi)置對(duì)象在其他瀏覽器中無(wú)效
  • 此API需要將請(qǐng)求參數(shù)進(jìn)行簽名(參與簽名的參數(shù)為:appId、timeStamp、nonceStr、package,參數(shù)區(qū)分大小寫(xiě))

示例代碼


function onBridgeReady() {
    WeixinJSBridge.invoke('getBrandWCPayRequest', {
        "appId": "wx2421b1c4370ecxxx",    //公眾號(hào)ID,由商戶(hù)傳入
        "timeStamp": "1395712654",     //時(shí)間戳,自1970年以來(lái)的秒數(shù)
        "nonceStr": "e61463f8efa94090b1f366cccfbbb444",    //隨機(jī)串
        "package": "prepay_id=up_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") {
            // 使用以上方式判斷前端返回,微信團(tuán)隊(duì)鄭重提示:
            //res.err_msg將在用戶(hù)支付成功后返回ok,但并不保證它絕對(duì)可靠。
        }
    });
}
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();
}
                    

重要入?yún)⒄f(shuō)明:

package:JSAPI下單接口返回的prepay_id參數(shù)值,提交格式如:prepay_id=***

signType:該接口V3版本僅支持RSA

paySign:簽名

paySign生成規(guī)則、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn) JSAPI調(diào)起支付接口文檔

3.2.3.【客戶(hù)端】APP調(diào)起支付

步驟說(shuō)明:通過(guò)APP下單API成功獲取預(yù)支付交易會(huì)話(huà)標(biāo)識(shí)(prepay_id)后,需要通過(guò)OpenSDK來(lái)調(diào)起微信支付收銀臺(tái)

注意:

  • 該步驟請(qǐng)使用開(kāi)放平臺(tái)的官方OpenSDK,可前往開(kāi)放平臺(tái)資源中心下載
  • SDK的調(diào)用需要攜帶簽名(參與簽名的參數(shù)為:appid、partnerid、prepayid、package、noncestr、timestamp,參數(shù)區(qū)分大小寫(xiě))
  • 重要入?yún)⒄f(shuō)明:
    • package:取固定值Sign=WXPay
    • signType:該接口V3版本僅支持RSA
    • paySign:簽名

    paySign生成規(guī)則、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn)APP調(diào)起支付接口文檔


iOS SDK調(diào)用說(shuō)明

一、拉起支付

商戶(hù)服務(wù)器生成支付訂單,先調(diào)用合單APP下單API生成預(yù)付單,獲取到prepay_id后將參數(shù)再次簽名傳輸給APP發(fā)起支付。以下是調(diào)起微信支付的關(guān)鍵代碼:


PayReq *request = [[[PayReq alloc] init] autorelease];

request.partnerId = @"10000100";

request.prepayId= @"1101000000140415649af9fc314aa427";

request.package = @"Sign=WXPay";

request.nonceStr= @"a462b76e7436e98e0ed6e13c64b4fd1c";

request.timeStamp= @"1397527777";

request.sign= @"582282D72DD2B03AD892830965F428CB16E7A256";

[WXApi sendReq:request]
                    

注意:該sign生成字段名列表見(jiàn)調(diào)起支付API

二、SDK結(jié)果回調(diào)

照微信SDK Sample,在類(lèi)實(shí)現(xiàn)onResp函數(shù),支付完成后,微信APP會(huì)返回到商戶(hù)APP并回調(diào)onResp函數(shù),開(kāi)發(fā)者需要在該函數(shù)中接收通知,判斷返回錯(cuò)誤碼,如果支付成功則去后臺(tái)查詢(xún)支付結(jié)果再展示用戶(hù)實(shí)際支付結(jié)果。注意 一定不能以客戶(hù)端返回作為用戶(hù)支付的結(jié)果,應(yīng)以服務(wù)器端的接收的支付結(jié)果通知或查詢(xún)API返回的結(jié)果為準(zhǔn)。代碼示例如下:


-(void)onResp:(BaseResp*)resp{

  if ([respisKindOfClass:[PayRespclass]]){

      PayResp*response=(PayResp*)resp;

      switch(response.errCode){

                  caseWXSuccess: //服務(wù)器端查詢(xún)支付結(jié)果通知或查詢(xún)API返回的結(jié)果再提示成功

                           NSlog(@"支付成功");

                  break;

                  default:

                           NSlog(@"支付失敗,retcode=%d",resp.errCode);

                  break;

        }

   }

}
                    

回調(diào)中errCode值列表:

名稱(chēng) 描述 解決方案
0 成功 展示成功頁(yè)面
-1 錯(cuò)誤 可能的原因:簽名錯(cuò)誤、未注冊(cè)APPID、項(xiàng)目設(shè)置APPID不正確、注冊(cè)的APPID與設(shè)置的不匹配、其他異常等。
-2 用戶(hù)取消 無(wú)需處理。發(fā)生場(chǎng)景:用戶(hù)不支付了,點(diǎn)擊取消,返回APP。

Android SDK調(diào)用說(shuō)明

一、SDK拉起支付

商戶(hù)服務(wù)器生成支付訂單,先調(diào)用【合單APP下單API】生成預(yù)付單,獲取到prepay_id后將參數(shù)再次簽名傳輸給APP發(fā)起支付。以下是調(diào)起微信支付的關(guān)鍵代碼:


IWXAPI api;

PayReq request = new PayReq();

request.appId = "wxd930ea5d5a258f4f";

request.partnerId = "1900000109";

request.prepayId= "1101000000140415649af9fc314aa427",;

request.packageValue = "Sign=WXPay";

request.nonceStr= "1101000000140429eb40476f8896f4c9";

request.timeStamp= "1398746574";

request.sign= "7FFECB600D7157C5AA49810D2D8F28BC2811827B";

api.sendReq(request);
                    

注意:該sign生成字段名列表見(jiàn)調(diào)起支付API

二、支付結(jié)果回調(diào)

參照微信SDK Sample,在net.sourceforge.simcpux.wxapi包路徑中實(shí)現(xiàn)WXPayEntryActivity類(lèi)(包名或類(lèi)名不一致會(huì)造成無(wú)法回調(diào)),在WXPayEntryActivity類(lèi)中實(shí)現(xiàn)onResp函數(shù),支付完成后,微信APP會(huì)返回到商戶(hù)APP并回調(diào)onResp函數(shù),開(kāi)發(fā)者需要在該函數(shù)中接收通知,判斷返回錯(cuò)誤碼,如果支付成功則去后臺(tái)查詢(xún)支付結(jié)果再展示用戶(hù)實(shí)際支付結(jié)果。注意一定不能以客戶(hù)端返回作為用戶(hù)支付的結(jié)果,應(yīng)以服務(wù)器端的接收的支付結(jié)果通知或查詢(xún)API返回的結(jié)果為準(zhǔn)。代碼示例如下:


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);

    }

}
                    

回調(diào)中errCode值列表:

名稱(chēng) 描述 解決方案
0 成功 展示成功頁(yè)面
-1 錯(cuò)誤 可能的原因:簽名錯(cuò)誤、未注冊(cè)APPID、項(xiàng)目設(shè)置APPID不正確、注冊(cè)的APPID與設(shè)置的不匹配、其他異常等。
-2 用戶(hù)取消 無(wú)需處理。發(fā)生場(chǎng)景:用戶(hù)不支付了,點(diǎn)擊取消,返回APP。
3.2.4. 【客戶(hù)端】小程序調(diào)起支付API

步驟說(shuō)明:通過(guò)小程序下單API成功獲取預(yù)支付交易會(huì)話(huà)標(biāo)識(shí)(prepay_id)后,需要通過(guò)小程序調(diào)起支付API來(lái)調(diào)起微信支付收銀臺(tái)

注意

  • 此API需要將請(qǐng)求參數(shù)進(jìn)行簽名(參與簽名的參數(shù)為:appId、timeStamp、nonceStr、package,參數(shù)區(qū)分大小寫(xiě))
  • appId必須為最后拉起收銀臺(tái)的小程序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){}
})
                    

重要入?yún)⒄f(shuō)明:

  • package:合單APP下單接口返回的prepay_id參數(shù)值,提交格式如:prepay_id=***
  • signType:該接口V3版本僅支持RSA
  • paySign:簽名
  • nonceStr:自定義隨機(jī)數(shù)

paySign生成規(guī)則、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn)小程序調(diào)起支付API接口文檔


3.2.5. 【客戶(hù)端】生成支付二維碼

步驟說(shuō)明:通過(guò)合單tive下單API成功獲取支付二維碼鏈接(code_url)后,需要在前端(PC網(wǎng)頁(yè)或POS機(jī)具)生成二維碼供用戶(hù)掃描支付。

注意

  • code_url對(duì)應(yīng)鏈接格式:weixin://weixin://www.tg885.com/bizpayurl/up?pr=NwY5Mz9&groupid=00。請(qǐng)商戶(hù)調(diào)用第三方庫(kù)將code_url生成二維碼圖片。該模式鏈接較短,生成的二維碼打印到結(jié)賬小票上的識(shí)別率較高。

    例如,將weixin://weixin://www.tg885.com/bizpayurl/up?pr=NwY5Mz9&groupid=00 生成二維碼建下圖

  • 更多二維碼的相關(guān)背景知識(shí)可參考

    https://www.thonky.com/qr-code-tutorial/

    https://coolshell.cn/articles/10590.html

3.2.6. 【客戶(hù)端】微信外H5瀏覽器拉起微信支付中間頁(yè)

步驟說(shuō)明:通過(guò)H5下單API成功獲取H5下單返回的支付中間頁(yè)(h5_url)后,用戶(hù)需要通過(guò)微信外部的瀏覽器調(diào)起微信支付收銀臺(tái)

注意

  • h5_url為拉起微信支付收銀臺(tái)的中間頁(yè)面,可通過(guò)訪問(wèn)該url來(lái)拉起微信客戶(hù)端,完成支付,h5_url的有效期為5分鐘
  • 微信支付收銀臺(tái)中間頁(yè)會(huì)進(jìn)行H5權(quán)限的校驗(yàn),安全性檢查
  • 正常流程用戶(hù)支付完成后會(huì)返回至發(fā)起支付的頁(yè)面,如需返回至指定頁(yè)面,則可以在h5_url后拼接上redirect_url參數(shù),來(lái)指定回調(diào)頁(yè)面。您希望用戶(hù)支付完成后跳轉(zhuǎn)至https://www.wechatpay.com.cn,則拼接后的地址為h5_url= https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096&redirect_url=https%3A%2F%2Fwww.wechatpay.com.cn
  • 需對(duì)redirect_url進(jìn)行urlencode處理
  • 由于設(shè)置redirect_url后,回跳指定頁(yè)面的操作可能發(fā)生在:

      1、微信支付中間頁(yè)調(diào)起微信收銀臺(tái)后超過(guò)5秒

       2、用戶(hù)點(diǎn)擊“取消支付”或支付完成后點(diǎn)“完成”按鈕。因此無(wú)法保證頁(yè)面回跳時(shí),支付流程已結(jié)束,所以商戶(hù)設(shè)置的redirect_url地址不能自動(dòng)執(zhí)行查單操作,應(yīng)讓用戶(hù)去點(diǎn)擊按鈕觸發(fā)查單操作,回跳頁(yè)面展示效果可參考下圖

更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn)H5調(diào)起支付API接口文檔

3.2.7.【服務(wù)端】接收支付結(jié)果通知

步驟說(shuō)明:當(dāng)用戶(hù)完成支付,微信會(huì)把相關(guān)支付結(jié)果將通過(guò)異步回調(diào)的方式通知商戶(hù),商戶(hù)需要接收處理,并按文檔規(guī)范返回應(yīng)答

  • 支付結(jié)果通知的地址需要在請(qǐng)求APP下單API時(shí)傳入notify_url參數(shù)中
  • 支付結(jié)果通知是以POST 方法訪問(wèn)商戶(hù)設(shè)置的通知url,通知的數(shù)據(jù)以JSON 格式通過(guò)請(qǐng)求主體(BODY)傳輸。通知的數(shù)據(jù)包括了加密的支付結(jié)果詳情
  • 加密不能保證通知請(qǐng)求來(lái)自微信。微信會(huì)對(duì)發(fā)送給商戶(hù)的通知進(jìn)行簽名,并將簽名值放在通知的HTTP頭Wechatpay-Signature。商戶(hù)應(yīng)當(dāng)驗(yàn)證簽名,以確認(rèn)請(qǐng)求來(lái)自微信,而不是其他的第三方。簽名驗(yàn)證的算法請(qǐng)參考 《微信支付API v3簽名驗(yàn)證》
  • 支付結(jié)果通知http應(yīng)答碼為200或204才會(huì)當(dāng)作正常接收,當(dāng)回調(diào)處理異常時(shí),應(yīng)答的HTTP狀態(tài)碼應(yīng)為500,或者4xx
  • 商戶(hù)成功接收到回調(diào)通知后應(yīng)返回成功的http應(yīng)答碼為200或204
  • 同樣的通知可能會(huì)多次發(fā)送給商戶(hù)系統(tǒng)。商戶(hù)系統(tǒng)必須能夠正確處理重復(fù)的通知。
  • 后臺(tái)通知交互時(shí),如果微信收到商戶(hù)的應(yīng)答不符合規(guī)范或超時(shí),微信會(huì)判定本次通知失敗,重新發(fā)送通知,直到成功為止,但微信不保證通知最終一定能成功

特別提醒:

  • 商戶(hù)系統(tǒng)對(duì)于支付結(jié)果通知的內(nèi)容一定要做簽名驗(yàn)證,并校驗(yàn)返回的訂單金額是否與商戶(hù)側(cè)的訂單金額一致,防止數(shù)據(jù)泄露導(dǎo)致出現(xiàn)“假通知”,造成資金損失。
  • 當(dāng)收到通知進(jìn)行處理時(shí),首先檢查對(duì)應(yīng)業(yè)務(wù)數(shù)據(jù)的狀態(tài),判斷該通知是否已經(jīng)處理過(guò),如果沒(méi)有處理過(guò)再進(jìn)行處理,如果處理過(guò)直接返回結(jié)果成功。在對(duì)業(yè)務(wù)數(shù)據(jù)進(jìn)行狀態(tài)檢查和處理之前,要采用數(shù)據(jù)鎖進(jìn)行并發(fā)控制,以避免函數(shù)重入造成的數(shù)據(jù)混亂。
  • 技術(shù)人員可登進(jìn)微信商戶(hù)后臺(tái)掃描加入接口報(bào)警群,獲取接口告警信息。

更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn)支付結(jié)果通知API接口文檔

3.2.8. 【服務(wù)端】合單查詢(xún)訂單

步驟說(shuō)明:當(dāng)商戶(hù)后臺(tái)、網(wǎng)絡(luò)、服務(wù)器等出現(xiàn)異常,商戶(hù)系統(tǒng)最終未接收到支付結(jié)果通知時(shí)商戶(hù)可通過(guò)查詢(xún)訂單接口核實(shí)訂單支付狀態(tài)

示例代碼

public void QueryOrder() throws Exception {

  //請(qǐng)求URL
  URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/combine-transactions/out-trade-no/P11093730578574");
  uriBuilder.setParameter("mchid", mchId);

  //完成簽名并執(zhí)行請(qǐng)求
  HttpGet httpGet = new HttpGet(uriBuilder.build());
  httpGet.addHeader("Accept", "application/json");
  CloseableHttpResponse response = httpClient.execute(httpGet);

  try {
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode == 200) {
          System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
      } else if (statusCode == 204) {
          System.out.println("success");
      } else {
          System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
          throw new IOException("request failed");
      }
  } finally {
      response.close();
  }
}
try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/combine-transactions/out-trade-no/P11093730578574', //請(qǐng)求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //處理成功
        echo "success,return body = " . $resp->getReasonPhrase()."\n";
    } else if ($statusCode == 204) { //處理成功,無(wú)返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 進(jìn)行錯(cuò)誤處理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
                    

注意:

  • 查詢(xún)訂單可通過(guò)合單商戶(hù)訂單號(hào)查詢(xún)

更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn) 查詢(xún)訂單API接口文檔


3.2.9. 【服務(wù)端】合單關(guān)閉訂單

步驟說(shuō)明:當(dāng)商戶(hù)訂單支付失敗需要生成新單號(hào)重新發(fā)起支付,要對(duì)原訂單號(hào)調(diào)用關(guān)單,避免重復(fù)支付;系統(tǒng)下單后,用戶(hù)支付超時(shí),系統(tǒng)退出不再受理,避免用戶(hù)繼續(xù),請(qǐng)調(diào)用關(guān)單接口

示例代碼


public void CombineCloseOrder() throws Exception{

  //請(qǐng)求URL
  HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/combine-transactions/out-trade-no/{combine_out_trade_no}/close");
  // 請(qǐng)求body參數(shù)
  String reqdata = "{"
          + "\"combine_appid \":\"wxd678efh567hg6787\","
          + "\"combine_out_trade_no\":\"P20150806125346\","
          + "\"sub_orders\": ["
          + "{"
          + "\"mchid\":\"1900000109\","
          + "\"out_trade_no\":\"20150806125346\","
          + "\"sub_mchid\":\"1230000109\","
          + "\"description\":\"騰訊充值中心-QQ會(huì)員充值\""
          + "}"
          + "]"
          + "}";
  StringEntity entity = new StringEntity(reqdata,"utf-8");
  entity.setContentType("application/json");
  httpPost.setEntity(entity);
  httpPost.setHeader("Accept", "application/json");

  //完成簽名并執(zhí)行請(qǐng)求
  CloseableHttpResponse response = httpClient.execute(httpPost);

  try {
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode == 200) { //處理成功
          System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
      } else if (statusCode == 204) { //處理成功,無(wú)返回Body
          System.out.println("success");
      } else {
          System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
          throw new IOException("request failed");
      }
  } finally {
      response.close();
  }
}

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/combine-transactions/out-trade-no/{combine_out_trade_no}/close', //請(qǐng)求URL
        [
            // JSON請(qǐng)求體
            'json' => [
                "combine_appid " => "wxd678efh567hg6787",
                "combine_out_trade_no" => "P20150806125346",
                "sub_orders" => [
                    [
                        "mchid" => "1900000109",
                        "out_trade_no" => "20150806125346",
                        "sub_mchid" => "1230000109",
                        "description" => "騰訊充值中心-QQ會(huì)員充值",
                    ],
                ]
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //處理成功
        echo "success,return body = " . $resp->getReasonPhrase()."\n";
    } else if ($statusCode == 204) { //處理成功,無(wú)返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 進(jìn)行錯(cuò)誤處理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}

注意:

  • 訂單生成后不能馬上調(diào)用關(guān)單接口,最短調(diào)用時(shí)間間隔為5分鐘
  • 已支付成功的訂單不能關(guān)閉

更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn) 合單關(guān)單API接口文檔

3.2.10. 【服務(wù)端】申請(qǐng)交易賬單

步驟說(shuō)明:微信支付按天提供交易賬單文件,商戶(hù)可以通過(guò)該接口獲取賬單文件的下載地址

示例代碼


public void TradeBill() throws Exception {

  //請(qǐng)求URL
  URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/bill/tradebill");
  uriBuilder.setParameter("bill_date", "2020-11-09");
  uriBuilder.setParameter("bill_type", "ALL");

  //完成簽名并執(zhí)行請(qǐng)求
  HttpGet httpGet = new HttpGet(uriBuilder.build());
  httpGet.addHeader("Accept", "application/json");
  CloseableHttpResponse response = httpClient.execute(httpGet);

  try {
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode == 200) {
          System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
      } else if (statusCode == 204) {
          System.out.println("success");
      } else {
          System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
          throw new IOException("request failed");
      }
  } finally {
      response.close();
  }
}
                    

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/bill/tradebill?bill_date=2019-06-11&sub_mchid=1900000001&bill_type=ALL', //請(qǐng)求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //處理成功
        echo "success,return body = " . $resp->getReasonPhrase()."\n";
    } else if ($statusCode == 204) { //處理成功,無(wú)返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 進(jìn)行錯(cuò)誤處理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
                    

更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn)申請(qǐng)交易賬單API 接口文檔


3.2.11. 【服務(wù)端】下載賬單

步驟說(shuō)明:通過(guò)申請(qǐng)交易賬單接口獲取到賬單下載地址(download_url)后,再通過(guò)該接口獲取到對(duì)應(yīng)的賬單文件,文件內(nèi)包含交易相關(guān)的金額、時(shí)間、營(yíng)銷(xiāo)等信息,供商戶(hù)核對(duì)訂單、退款、銀行到賬等情況

示例代碼


public void DownloadUrl(String download_url) throws Exception{
  PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));

  //初始化httpClient
  //該接口無(wú)需進(jìn)行簽名驗(yàn)證、通過(guò)withValidator((response) -> true)實(shí)現(xiàn)
  httpClient =  WechatPayHttpClientBuilder.create().withMerchant(mchId, mchSerialNo, merchantPrivateKey).withValidator((response) -> true).build();

  //請(qǐng)求URL
  //賬單文件的下載地址的有效時(shí)間為30s
  URIBuilder uriBuilder = new URIBuilder(download_url);
  HttpGet httpGet = new HttpGet(uriBuilder.build());
  httpGet.addHeader("Accept", "application/json");

  //執(zhí)行請(qǐng)求
  CloseableHttpResponse response = httpClient.execute(httpGet);
  try {
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode == 200) {
          System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
      } else if (statusCode == 204) {
          System.out.println("success");
      } else {
          System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
          throw new IOException("request failed");
      }
  } finally {
      response.close();
  }
}
                                    

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/billdownload/file?token=xx', //請(qǐng)求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //處理成功
        echo "success,return body = " . $resp->getReasonPhrase()."\n";
    } else if ($statusCode == 204) { //處理成功,無(wú)返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 進(jìn)行錯(cuò)誤處理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
                                    

注意:

  • 賬單文件的下載地址的有效時(shí)間為30s
  • 強(qiáng)烈建議商戶(hù)將實(shí)際賬單文件的哈希值和之前從接口獲取到的哈希值進(jìn)行比對(duì),以確認(rèn)數(shù)據(jù)的完整性

更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn) 下載賬單API接口文檔


4. 常見(jiàn)問(wèn)題

Q:獲取OPENID接口報(bào)“此公眾號(hào)并沒(méi)有這些scope的權(quán)限,錯(cuò)誤碼10005”,如下圖所示

A:請(qǐng)按以下步驟進(jìn)行排查:

    1.建議檢查一下公眾號(hào)的功能。比如是不是在訂閱號(hào)/未認(rèn)證的公眾號(hào)里面嘗試調(diào)用認(rèn)證服務(wù)號(hào)的功能

    2.確認(rèn)APPID是否認(rèn)證過(guò)期或者APPID填寫(xiě)錯(cuò)誤

    3.請(qǐng)嘗試使用snsapi_userinfo的授權(quán)登錄方式

Q:JSAPI調(diào)起支付接口報(bào)“商家暫時(shí)沒(méi)有此類(lèi)交易權(quán)限,請(qǐng)聯(lián)系商家客服”

A:請(qǐng)按以下步驟進(jìn)行排查:

    1.請(qǐng)檢查你的下單接口是否指定了支付用戶(hù)的身份,該功能需單獨(dú)開(kāi)通指定身份支付權(quán)限方可使用

    2.請(qǐng)確認(rèn)你使用的商戶(hù)號(hào)是否有jsapi支付的權(quán)限,可登錄商戶(hù)平臺(tái)-產(chǎn)品中心查看

Q:JSAPI調(diào)起支付接口報(bào)“當(dāng)前頁(yè)面的URL未注冊(cè)”

A:請(qǐng)檢查下單接口中使用的商戶(hù)號(hào)是否在商戶(hù)平臺(tái)(www.tg885.com)配置了對(duì)應(yīng)的支付目錄,可參考“1.2.1設(shè)置支付目錄”章節(jié)說(shuō)明

Q :獲取OPENID接口報(bào)“redirect_url域名與后臺(tái)配置不一致,錯(cuò)誤碼:10003”

A:請(qǐng)按以下步驟進(jìn)行排查:

    1.檢查下單接口傳的appid與獲取openid接口的appid是否同一個(gè)(需一致)

    2.檢查appid對(duì)應(yīng)的公眾號(hào)后臺(tái)(mp.weixin.qq.com),是否配置的授權(quán)域名和獲取openid的域名一致。授權(quán)域名配置路徑:公眾平臺(tái)--設(shè)置--公眾號(hào)設(shè)置--功能設(shè)置–網(wǎng)頁(yè)授權(quán)域名

Q :JSAPI調(diào)起支付接口報(bào)“該商戶(hù)暫不支持通過(guò)外部拉起微信完成支付”

A:JSAPI支付只能從微信瀏覽器內(nèi)發(fā)起支付請(qǐng)求



技術(shù)咨詢(xún)

文檔反饋