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

基礎(chǔ)支付
JSAPI支付
APP支付
H5支付
Native支付
小程序支付
合單支付
付款碼支付
經(jīng)營能力
微信支付分
支付即服務(wù)
行業(yè)方案
智慧商圈
微信支付分停車服務(wù)
電子發(fā)票
營銷工具
代金券
商家券
委托營銷
支付有禮
小程序發(fā)券插件
H5發(fā)券
圖片上傳(營銷專用)
現(xiàn)金紅包
資金應(yīng)用
商家轉(zhuǎn)賬到零錢
分賬
風(fēng)險(xiǎn)合規(guī)
消費(fèi)者投訴2.0
其他能力
清關(guān)報(bào)關(guān)
圖片上傳
視頻上傳
微信支付平臺證書

微信支付分開發(fā)指引(需確認(rèn)模式)

1. 接口規(guī)則

為了在保證支付安全的前提下,帶給商戶簡單、一致且易用的開發(fā)體驗(yàn),我們推出了全新的微信支付APIv3接口。該版本API的具體規(guī)則請參考“APIv3接口規(guī)則
備注:當(dāng)前接口用于微信國內(nèi)錢包

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

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

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

測試步驟

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

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

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

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

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

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

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


@Before
public void setup() throws IOException {
    // 加載商戶私鑰(privateKey:私鑰字符串)
    PrivateKey merchantPrivateKey = PemUtil
            .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
 
    // 加載平臺證書(mchId:商戶號,mchSerialNo:商戶證書序列號,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;
 
// 商戶相關(guān)配置,
$merchantId = '1000100'; // 商戶號
$merchantSerialNumber = 'XXXXXXXXXX'; // 商戶API證書序列號
$merchantPrivateKey = PemUtil::loadPrivateKey('./path/to/mch/private/key.pem'); // 商戶私鑰文件路徑
 
// 微信支付平臺配置
$wechatpayCertificate = PemUtil::loadCertificate('./path/to/wechatpay/cert.pem'); // 微信支付平臺證書文件路徑
 
// 構(gòu)造一個(gè)WechatPayMiddleware
$wechatpayMiddleware = WechatPayMiddleware::builder()
    ->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 傳入商戶相關(guān)配置
    ->withWechatPay([ $wechatpayCertificate ]) // 可傳入多個(gè)微信支付平臺證書,參數(shù)類型為array
    ->build();
 
// 將WechatPayMiddleware添加到Guzzle的HandlerStack中
$stack = GuzzleHttp\HandlerStack::create();
$stack->push($wechatpayMiddleware, 'wechatpay');
 
// 創(chuàng)建Guzzle HTTP Client時(shí),將HandlerStack傳入,接下來,正常使用Guzzle發(fā)起API請求,WechatPayMiddleware會自動地處理簽名和驗(yàn)簽
$client = new GuzzleHttp\Client(['handler' => $stack]);

/*
    Package core 微信支付api v3 go http-client 基礎(chǔ)庫,你可以使用它來創(chuàng)建一個(gè)client,并向微信支付發(fā)送http請求
    只需要你在初始化客戶端的時(shí)候,傳遞credential以及validator
    credential用來生成http header中的authorization信息
    validator則用來校驗(yàn)回包是否被篡改
    如果http請求返回的err為nil,一般response.Body 都不為空,你可以嘗試對其進(jìn)行序列化
    請注意及時(shí)關(guān)閉response.Body
    注意:使用微信支付apiv3 go庫需要引入相關(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) {
    //商戶號
    mchID := ""
    //商戶證書序列號
    mchCertSerialNumber := ""
    //商戶私鑰文件路徑
    privateKeyPath := ""
    //平臺證書文件路徑
    wechatCertificatePath := ""

    // 加載商戶私鑰
    privateKey, err := utils.LoadPrivateKeyWithPath(privateKeyPath)
    if err != nil {
        log.Printf("load private err:%s", err.Error())
        return nil, err
    }
    // 加載微信支付平臺證書
    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è)置商戶相關(guān)配置
        option.WithWechatPay([]*x509.Certificate{wechatPayCertificate}), // 設(shè)置微信支付平臺證書,用于校驗(yàn)回包信息用
    }
    return opts, nil
}

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

說明:

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

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

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

    1.簽名生成

    2.簽名驗(yàn)證

    3.敏感信息加解密

    4.merchantPrivateKey(私鑰)

    5.wechatpayCertificates(平臺證書)

    6.APIV3Key(V3 key)

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

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

1、微信支付分的相關(guān)配置參數(shù)在商戶入駐的過程中都已經(jīng)配置完成(前往查看配置相關(guān)內(nèi)容),例如授權(quán)結(jié)果回調(diào)url、service_notify_url、測試白名單、免確認(rèn)訂單模式的權(quán)限等。

2、如果發(fā)現(xiàn)配置信息有誤,請主動聯(lián)系微信支付分運(yùn)營同學(xué)協(xié)助修改,或者點(diǎn)擊右側(cè)導(dǎo)航欄進(jìn)入在線技術(shù)客服進(jìn)行技術(shù)咨詢。


3. 快速接入(需確認(rèn)模式)

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

重點(diǎn)步驟說明:

步驟1 用戶在商戶側(cè)下單,商戶調(diào)用后臺接口創(chuàng)建支付分訂單,通過接口返回獲得跳轉(zhuǎn)微信支付分小程序進(jìn)行訂單確認(rèn)的必填參數(shù)“package”

我們通過此接口來創(chuàng)建支付分訂單:創(chuàng)建支付分訂單API

  • 入?yún)ⅰ皀eed_user_confirm”,取值請選擇 “true”;
  • 入?yún)ⅰ皉isk_fund:name”,取值請選擇【先免模式】中的枚舉值。

步驟2 調(diào)用前端方法跳轉(zhuǎn)至微信,讓用戶完成確認(rèn)訂單操作

我們通過以下前端方法可調(diào)起微信客戶端(注意區(qū)分場景):


步驟3 用戶確認(rèn)訂單完成,商戶系統(tǒng)將收到確認(rèn)訂單回調(diào)通知,此時(shí)可為用戶提供服務(wù);

我們通過以下接口將用戶確認(rèn)訂單信息回調(diào)通知給商戶系統(tǒng):

? 確認(rèn)訂單回調(diào)通知API

在用戶確認(rèn)訂單過程中可能出現(xiàn)長時(shí)間未收到回調(diào)、用戶確認(rèn)失敗等情況,商戶可先通過后臺接口查詢訂單狀態(tài):

? 查詢支付分訂單API

根據(jù)查詢到的訂單狀態(tài)結(jié)果,商戶可決定是否需要取消當(dāng)前訂單,后臺接口為:

? 取消支付分訂單API


步驟4 用戶服務(wù)結(jié)束,商戶通過后臺接口完結(jié)支付分訂單;

調(diào)用完結(jié)支付分訂單API接口后,微信支付分就會發(fā)起對用戶的扣款,但是在用戶扣款過程中可能會出現(xiàn)一些特殊情況,下面列舉了幾種特殊情況以及對應(yīng)的處理方法,供大家參考:

請求:

? 情況一:扣款過程中,發(fā)現(xiàn)扣款金額有誤(注意:此時(shí)需要訂單為“待支付”狀態(tài))

處理方法1:調(diào)用修改訂單金額接口修改訂單金額,系統(tǒng)將按照修改后的金額發(fā)起用戶扣款

處理方法2:調(diào)用取消支付分訂單接口取消待支付的支付分訂單

? 情況二:扣款過程中,用戶通過其它方式完成了支付,希望微信支付分停止繼續(xù)扣款

處理方法:商戶調(diào)用同步服務(wù)訂單信息接口將訂單支付成功狀態(tài)同步給微信支付分,微信支付分將停止繼續(xù)扣款的操作


步驟5 收到用戶扣款成功通知,業(yè)務(wù)流程結(jié)束

通過支付成功回調(diào)通知API接口可以獲取到用戶扣款成功的通知,同時(shí),商戶也可以根據(jù)情況通過查詢支付分訂單API接口主動查詢扣款情況。

  • 如訂單狀態(tài)state=DONE,且收款狀態(tài)collection.state=USER_PAID,代表扣款成功
  • 如訂單狀態(tài)state=DOING,state_description=MCH_COMPLETE,且收款狀態(tài)collection.state=USER_PAYING,代表扣款進(jìn)行中

如遇到網(wǎng)絡(luò)、服務(wù)器等原因造成無法正常接收扣款成功通知,一般有兩種解決方法:

1.主動查單,通過查詢支付分訂單API 接口主動查詢扣款情況

2.次日對賬,通過申請交易賬單API接口申請交易賬單,再通過后臺接口下載賬單API下載交易賬單


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

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

注意:

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

步驟說明:完成用戶授權(quán)后,即可創(chuàng)建支付分訂單,為用戶提供服務(wù)了。

示例代碼

public void CreateServiceOrder() throws Exception{
  
    //請求URL
    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/serviceorder");
    // 請求body參數(shù)
    String reqdata = "{"
            + "\"out_order_no\":\"1234323JKHDFE1243252\","
            + "\"appid\":\"wxd678efh567hg6787\","
            + "\"service_id\":\"500001\","
            + "\"service_introduction\":\"某某酒店\","
            + "\"post_payments\": ["
            + "{"
            + "\"name\":\"就餐費(fèi)用服務(wù)費(fèi)\","
            + "\"amount\":4000,"
            + "\"description\":\"就餐人均100元服務(wù)費(fèi):100/小時(shí)\","
            + "\"count\":1"
            + "}"
            + "],"
            + "\"post_discounts\": ["
            + "{"
            + "\"name\":\"滿20減1元\","
            + "\"description\":\"不與其他優(yōu)惠疊加\""
            + "}"
            + "],"
            + "\"time_range\": {"
            + "\"start_time\":\"20091225091010\","
            + "\"end_time\":\"20091225121010\""
            + "},"
            + "\"location\": {"
            + "\"start_location\":\"嗨客時(shí)尚主題展餐廳\","
            + "\"end_location\":\"嗨客時(shí)尚主題展餐廳\""
            + "},"
            + "\"risk_fund\": {"
            + "\"name\":\"ESTIMATE_ORDER_COST\","
            + "\"amount\":10000,"
            + "\"description\":\"就餐的預(yù)估費(fèi)用\""
            + "},"
            + "\"attach\":\"Easdfowealsdkjfnlaksjdlfkwqoi&wl3l2sald\","
            + "\"notify_url\":\"https://api.test.com\","
            + "\"openid\":\"oUpF8uMuAJO_M2pxb1Q9zNjWeS6o\","
            + "\"need_user_confirm\":true"
            + "}";
    StringEntity entity = new StringEntity(reqdata,"utf-8");
    entity.setContentType("application/json");
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept", "application/json");
    
    //完成簽名并執(zhí)行請求
    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) { //處理成功,無返回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/payscore/serviceorder', //請求URL
        [
            // JSON請求體
            'json' => [
                "out_order_no" => "1234323JKHDFE1243252",
                "appid" => "wxd678efh567hg6787",
                "service_id" => "500001",
                "service_introduction" => "某某酒店",
                "post_payments" => [
                    [
                        "name" => "就餐費(fèi)用服務(wù)費(fèi)",
                        "amount" => 4000,
                        "description" => "就餐人均100元服務(wù)費(fèi):100/小時(shí)",
                        "count" => 1,
                    ],
                ],
                "post_discounts" => [
                    [
                        "name" => "滿20減1元",
                        "description" => "不與其他優(yōu)惠疊加",
                    ],
                ],
                "time_range" => [
                    "start_time" => "20091225091010",
                    "end_time" => "20091225121010",
                ],
                "location" => [
                    "start_location" => "嗨客時(shí)尚主題展餐廳",
                    "end_location" => "嗨客時(shí)尚主題展餐廳",
                ],
                "risk_fund" => [
                    "name" => "ESTIMATE_ORDER_COST",
                    "amount" => 10000,
                    "description" => "就餐的預(yù)估費(fèi)用",
                ],
                "attach" => "Easdfowealsdkjfnlaksjdlfkwqoi&wl3l2sald",
                "notify_url" => "https://api.test.com",
                "openid" => "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o",
                "need_user_confirm" => true,
            ],
            '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) {
    // 進(jìn)行錯誤處理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
  }

重要參數(shù)說明

? 入?yún)ⅰ皀eed_user_confirm”,取值請選擇 “true”;

? 入?yún)ⅰ皉isk_fund:name”,取值請選擇【先免模式】中的枚舉值。

更多參數(shù)、響應(yīng)詳情及錯誤碼請參見創(chuàng)建支付分訂單API接口文檔

3.2.2.【客戶端】跳轉(zhuǎn)確認(rèn)訂單頁

微信支付根據(jù)用戶不同的使用場景(APP、小程序、微信內(nèi)H5)分別提供了對應(yīng)跳轉(zhuǎn)確認(rèn)訂單頁的方法,請根據(jù)場景進(jìn)行選擇,詳見跳轉(zhuǎn)確認(rèn)訂單頁API文檔

3.2.3.【服務(wù)端】確認(rèn)訂單回調(diào)通知

步驟說明:當(dāng)用戶確認(rèn)訂單時(shí),微信會把相關(guān)信息異步回調(diào)的方式通知商戶,商戶需要接收處理,并按文檔規(guī)范返回應(yīng)答

注意:
  • 支付結(jié)果通知是以POST 方法訪問商戶設(shè)置的通知url,通知的數(shù)據(jù)以JSON 格式通過請求主體(BODY)傳輸。通知的數(shù)據(jù)包括了加密的支付結(jié)果詳情
  • 加密不能保證通知請求來自微信。微信會對發(fā)送給商戶的通知進(jìn)行簽名,并將簽名值放在通知的HTTP頭Wechatpay-Signature。商戶應(yīng)當(dāng)驗(yàn)證簽名,以確認(rèn)請求來自微信,而不是其他的第三方。簽名驗(yàn)證的算法請參考 《微信支付API v3簽名驗(yàn)證》
  • 支付通知http應(yīng)答碼為200或204才會當(dāng)作正常接收,當(dāng)回調(diào)處理異常時(shí),應(yīng)答的HTTP狀態(tài)碼應(yīng)為500,或者4xx
  • 商戶成功接收到回調(diào)通知后應(yīng)返回成功的http應(yīng)答碼為200或204
  • 同樣的通知可能會多次發(fā)送給商戶系統(tǒng)。商戶系統(tǒng)必須能夠正確處理重復(fù)的通知。 推薦的做法是,當(dāng)商戶系統(tǒng)收到通知進(jìn)行處理時(shí),先檢查對應(yīng)業(yè)務(wù)數(shù)據(jù)的狀態(tài),并判斷該通知是否已經(jīng)處理。如果未處理,則再進(jìn)行處理;如果已處理,則直接返回結(jié)果成功。在對業(yè)務(wù)數(shù)據(jù)進(jìn)行狀態(tài)檢查和處理之前,要采用數(shù)據(jù)鎖進(jìn)行并發(fā)控制,以避免函數(shù)重入造成的數(shù)據(jù)混亂。
  • 如果在所有通知頻率(4小時(shí))后沒有收到微信側(cè)回調(diào),商戶應(yīng)調(diào)用查詢訂單接口確認(rèn)訂單狀態(tài)。

更多參數(shù)、響應(yīng)詳情及錯誤碼請參見確認(rèn)訂單回調(diào)通知API接口文檔

3.2.4.【服務(wù)端】查詢支付分訂單

步驟說明:一般在創(chuàng)建訂單后、訂單完結(jié)成功后等關(guān)鍵流程中,商戶可能有知曉訂單狀態(tài)的需求,此時(shí)即可通過該接口查詢訂單狀態(tài)。

示例代碼:
public void GetServiceOrder() throws Exception{

  //請求URL
  HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/payscore/serviceorder?service_id=500001&out_order_no=8416518464133&appid=wxd678efh567hg6787");
  httpGet.setHeader("Accept", "application/json");
  
  //完成簽名并執(zhí)行請求
  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) { //處理成功,無返回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(
      'GET',
      'https://api.mch.weixin.qq.com/v3/payscore/serviceorder?service_id=500001&out_order_no=8416518464133&appid=wxd678efh567hg6787', //請求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) {
  // 進(jìn)行錯誤處理
  echo $e->getMessage()."\n";
  if ($e->hasResponse()) {
      echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
  }
  return;
}
3.2.5. 【服務(wù)端】取消支付分訂單

步驟說明:訂單為以下狀態(tài)時(shí)可以取消訂單:CREATED(已創(chuàng)單)、DOING(進(jìn)行中)(包括商戶完結(jié)支付分訂單后,且支付分訂單收款狀態(tài)為待支付USER_PAYING)。

示例代碼

public void CancelServiceOrder() throws Exception{

  //請求URL
  HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/serviceorder/{out_order_no}/cancel");
  // 請求body參數(shù)
  String reqdata = "{"
          + "\"appid\":\"wxd678efh567hg6787\","
          + "\"service_id\":\"500001\","
          + "\"reason\":\"用戶投訴\""
          + "}";
  StringEntity entity = new StringEntity(reqdata,"utf-8");
  entity.setContentType("application/json");
  httpPost.setEntity(entity);
  httpPost.setHeader("Accept", "application/json");
  
  //完成簽名并執(zhí)行請求
  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) { //處理成功,無返回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/payscore/serviceorder/{out_order_no}/cancel', //請求URL
      [
          // JSON請求體
          'json' => [
              "appid" => "wxd678efh567hg6787",
              "service_id" => "500001",
              "reason" => "用戶投訴",
          ],
          '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) {
  // 進(jìn)行錯誤處理
  echo $e->getMessage()."\n";
  if ($e->hasResponse()) {
      echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
  }
  return;
  }

更多參數(shù)、響應(yīng)詳情及錯誤碼請參見 取消支付分訂單API接口文檔

3.2.6.【服務(wù)端】完結(jié)支付分訂單

步驟說明:用戶服務(wù)結(jié)束后,商戶通過請求完結(jié)支付分訂單接口,通過微信支付分進(jìn)行用戶扣款操作。

注意:


public void CompleteServiceOrder() throws Exception{

  //請求URL
  HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/serviceorder/{out_order_no}/complete");
  // 請求body參數(shù)
  String reqdata = "{"
          + "\"appid\":\"wxd678efh567hg6787\","
          + "\"service_id\":\"500001\","
          + "\"post_payments\": ["
          + "{"
          + "\"name\":\"就餐費(fèi)用服務(wù)費(fèi)\","
          + "\"amount\":4000,"
          + "\"description\":\"就餐人均100元服務(wù)費(fèi):100/小時(shí)\","
          + "\"count\":1"
          + "}"
          + "],"
          + "\"post_discounts\": ["
          + "{"
          + "\"name\":\"滿20減1元\","
          + "\"description\":\"不與其他優(yōu)惠疊加\","
          + "\"amount\":4000"
          + "}"
          + "],"
          + "\"total_amount\":3900,"
          + "\"time_range\": {"
          + "\"start_time\":\"20091225091010\","
          + "\"end_time\":\"20091225121010\""
          + "},"
          + "\"location\": {"
          + "\"end_location\":\"嗨客時(shí)尚主題展餐廳\""
          + "},"
          + "\"profit_sharing\":false"
          + "}";
  StringEntity entity = new StringEntity(reqdata,"utf-8");
  entity.setContentType("application/json");
  httpPost.setEntity(entity);
  httpPost.setHeader("Accept", "application/json");
  
  //完成簽名并執(zhí)行請求
  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) { //處理成功,無返回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/payscore/serviceorder/{out_order_no}/complete', //請求URL
      [
          // JSON請求體
          'json' => [
              "appid" => "wxd678efh567hg6787",
              "service_id" => "500001",
              "post_payments" => [
                  [
                      "name" => "就餐費(fèi)用服務(wù)費(fèi)",
                      "amount" => 4000,
                      "description" => "就餐人均100元服務(wù)費(fèi):100/小時(shí)",
                      "count" => 1,
                  ],
              ],
              "post_discounts" => [
                  [
                      "name" => "滿20減1元",
                      "description" => "不與其他優(yōu)惠疊加",
                      "amount" => 4000,
                  ],
              ],
              "total_amount" => 3900,
              "time_range" => [
                  "start_time" => "20091225091010",
                  "end_time" => "20091225121010",
              ],
              "location" => [
                  "end_location" => "嗨客時(shí)尚主題展餐廳",
              ],
              "profit_sharing" => false,
          ],
          '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) {
  // 進(jìn)行錯誤處理
  echo $e->getMessage()."\n";
  if ($e->hasResponse()) {
      echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
  }
  return;
}

更多參數(shù)、響應(yīng)詳情及錯誤碼請參見完結(jié)支付分訂單API接口文檔

3.2.7. 【服務(wù)端】修改訂單金額

步驟說明:在用戶扣款成功前、完結(jié)訂單后(即訂單狀態(tài)為“待支付”),如需修改訂單支付金額,可通過此接口進(jìn)行訂單金額修改。修改成功后,微信支付將按照修改后的金額進(jìn)行用戶扣款。

示例代碼

public void ModifyServiceOrder() throws Exception{

  //請求URL
  HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/serviceorder/{out_order_no}/modify");
  // 請求body參數(shù)
  String reqdata = "{"
          + "\"appid\":\"wxd678efh567hg6787\","
          + "\"service_id\":\"500001\","
          + "\"post_payments\": ["
          + "{"
          + "\"name\":\"就餐費(fèi)用服務(wù)費(fèi)\","
          + "\"amount\":4000,"
          + "\"description\":\"就餐人均100元服務(wù)費(fèi):100/小時(shí)\","
          + "\"count\":1"
          + "}"
          + "],"
          + "\"post_discounts\": ["
          + "{"
          + "\"name\":\"滿20減1元\","
          + "\"description\":\"不與其他優(yōu)惠疊加\","
          + "\"amount\":100"
          + "}"
          + "],"
          + "\"total_amount\":2000,"
          + "\"reason\":\"用戶投訴\""
          + "}";
  StringEntity entity = new StringEntity(reqdata,"utf-8");
  entity.setContentType("application/json");
  httpPost.setEntity(entity);
  httpPost.setHeader("Accept", "application/json");

  //完成簽名并執(zhí)行請求
  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) { //處理成功,無返回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/payscore/serviceorder/{out_order_no}/modify', //請求URL
      [
          // JSON請求體
          'json' => [
              "appid" => "wxd678efh567hg6787",
              "service_id" => "500001",
              "post_payments" => [
                  [
                      "name" => "就餐費(fèi)用服務(wù)費(fèi)",
                      "amount" => 4000,
                      "description" => "就餐人均100元服務(wù)費(fèi):100/小時(shí)",
                      "count" => 1,
                  ],
              ],
              "post_discounts" => [
                  [
                      "name" => "滿20減1元",
                      "description" => "不與其他優(yōu)惠疊加",
                      "amount" => 100,
                  ],
              ],
              "total_amount" => 2000,
              "reason" => "用戶投訴",
          ],
          '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) {
  // 進(jìn)行錯誤處理
  echo $e->getMessage()."\n";
  if ($e->hasResponse()) {
      echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
  }
  return;
  }

更多參數(shù)、響應(yīng)詳情及錯誤碼請參見修改訂單金額API接口文檔

3.2.8【服務(wù)端】同步服務(wù)訂單信息

步驟說明:由于一些原因,用戶與商戶達(dá)成線下支付或者其他支付方式支付的協(xié)議,商戶可通過此接口告知微信支付該筆訂單無需繼續(xù)扣款,微信支付在接到此信息后將不再發(fā)起用戶扣款。

示例代碼:

public void SyncServiceOrder() throws Exception{
//請求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/serviceorder/{out_order_no}/sync");
// 請求body參數(shù)
String reqdata = "{"
        + "\"appid\":\"wxd678efh567hg6787\","
        + "\"service_id\":\"500001\","
        + "\"type\":\"Order_Paid\","
        + "\"detail\": {"
        + "\"paid_time\":\"20091225091210\""
        + "}"
        + "}";
StringEntity entity = new StringEntity(reqdata,"utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");

//完成簽名并執(zhí)行請求
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) { //處理成功,無返回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/payscore/serviceorder/{out_order_no}/sync', //請求URL
  [
      // JSON請求體
      'json' => [
          "appid" => "wxd678efh567hg6787",
          "service_id" => "500001",
          "type" => "Order_Paid",
          "detail" => [
              "paid_time" => "20091225091210",
          ]
      ],
      '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) {
// 進(jìn)行錯誤處理
echo $e->getMessage()."\n";
if ($e->hasResponse()) {
  echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
}
return;
}

更多參數(shù)、響應(yīng)詳情及錯誤碼請參見 同步服務(wù)訂單信息API接口文檔

3.2.9【服務(wù)端】申請交易賬單

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

示例代碼:

public void TradeBill() throws Exception {

  //請求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í)行請求
  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', //請求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) {
  // 進(jìn)行錯誤處理
  echo $e->getMessage()."\n";
  if ($e->hasResponse()) {
      echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
  }
  return;
}

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

3.2.10【服務(wù)端】下載交易賬單

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

示例代碼

public void DownloadUrl(String download_url) throws Exception{
  PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
    
  //初始化httpClient
  //該接口無需進(jìn)行簽名驗(yàn)證、通過withValidator((response) -> true)實(shí)現(xiàn)
  httpClient =  WechatPayHttpClientBuilder.create().withMerchant(mchId, mchSerialNo, merchantPrivateKey).withValidator((response) -> true).build();
    
  //請求URL
  //賬單文件的下載地址的有效時(shí)間為30s
  URIBuilder uriBuilder = new URIBuilder(download_url);
  HttpGet httpGet = new HttpGet(uriBuilder.build());
  httpGet.addHeader("Accept", "application/json");
    
  //執(zhí)行請求
  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', //請求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) {
  // 進(jìn)行錯誤處理
  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)烈建議商戶將實(shí)際賬單文件的哈希值和之前從接口獲取到的哈希值進(jìn)行比對,以確認(rèn)數(shù)據(jù)的完整性

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

3.2.11【服務(wù)端】支付成功回調(diào)通知

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

注意:

  • 支付結(jié)果通知是以POST 方法訪問商戶設(shè)置的通知url,通知的數(shù)據(jù)以JSON 格式通過請求主體(BODY)傳輸。通知的數(shù)據(jù)包括了加密的支付結(jié)果詳情
  • 加密不能保證通知請求來自微信。微信會對發(fā)送給商戶的通知進(jìn)行簽名,并將簽名值放在通知的HTTP頭Wechatpay-Signature。商戶應(yīng)當(dāng)驗(yàn)證簽名,以確認(rèn)請求來自微信,而不是其他的第三方。簽名驗(yàn)證的算法請參考 《微信支付API v3簽名驗(yàn)證》
  • 支付通知http應(yīng)答碼為200或204才會當(dāng)作正常接收,當(dāng)回調(diào)處理異常時(shí),應(yīng)答的HTTP狀態(tài)碼應(yīng)為500,或者4xx
  • 商戶成功接收到回調(diào)通知后應(yīng)返回成功的http應(yīng)答碼為200或204
  • 同樣的通知可能會多次發(fā)送給商戶系統(tǒng)。商戶系統(tǒng)必須能夠正確處理重復(fù)的通知。 推薦的做法是,當(dāng)商戶系統(tǒng)收到通知進(jìn)行處理時(shí),先檢查對應(yīng)業(yè)務(wù)數(shù)據(jù)的狀態(tài),并判斷該通知是否已經(jīng)處理。如果未處理,則再進(jìn)行處理;如果已處理,則直接返回結(jié)果成功。在對業(yè)務(wù)數(shù)據(jù)進(jìn)行狀態(tài)檢查和處理之前,要采用數(shù)據(jù)鎖進(jìn)行并發(fā)控制,以避免函數(shù)重入造成的數(shù)據(jù)混亂。
  • 如果在所有通知頻率(4小時(shí))后沒有收到微信側(cè)回調(diào),商戶應(yīng)調(diào)用查詢訂單接口確認(rèn)訂單狀態(tài)。

更多參數(shù)、響應(yīng)詳情及錯誤碼請參見 支付成功回調(diào)通知API接口文檔

3.2.12【客戶端】跳轉(zhuǎn)訂單詳情

微信支付根據(jù)用戶不同的使用場景(APP、小程序、微信內(nèi)H5)分別提供了對應(yīng)跳轉(zhuǎn)訂單詳情頁的方法,請根據(jù)場景進(jìn)行選擇,詳見跳轉(zhuǎn)訂單詳情頁API文檔

4. 常見問題

Q:需確認(rèn)訂單模式,同一個(gè)用戶可以下多少筆免押訂單,如果該用戶有未完結(jié)的支付分訂單,會不會影響用戶下一筆訂單免押

A:同一個(gè)用戶可以確認(rèn)免押訂單進(jìn)行中的筆數(shù)是3筆(未完結(jié)&未支付的訂單筆數(shù),產(chǎn)品策略,可能會調(diào)整);如果用戶進(jìn)行中的訂單超過3筆,則需要進(jìn)行押金支付,如果有任何1筆待支付的訂單,都是需要去支付押金的。

Q:商戶小程序跳轉(zhuǎn)支付分小程序(詳情頁,確認(rèn)頁)報(bào)錯“未通過申請,當(dāng)前服務(wù)未上線”

A:檢查測試微信是否開通白名單,提供服務(wù)id和微信號聯(lián)系運(yùn)營開通白名單

Q:創(chuàng)建支付分訂單返回{"code":"NO_AUTH","message":"商戶暫無權(quán)限使用此服務(wù)"}

A:① 檢查商戶號和appid是否配置了通用化接口權(quán)限,可以聯(lián)系微信側(cè)運(yùn)營確認(rèn)和配置通用化接口權(quán)限

② 如果商戶開通的是免確認(rèn)訂單權(quán)限,創(chuàng)建訂單時(shí)need_user_confirm只能傳false,如果商戶開通的是含確認(rèn)訂單權(quán)限,創(chuàng)建訂單時(shí)need_user_confirm只能傳true

創(chuàng)建支付分訂單返回{"code":"PARAM_ERROR","message":"訂單風(fēng)險(xiǎn)金額名稱不符合要求"}

A:檢查商戶號開通的是哪種模式的權(quán)限,需確認(rèn)模式只能使用先免模式,免確認(rèn)模式只能使用先享模式模式

Q:調(diào)用支付分創(chuàng)單接口報(bào)錯返回“mch_id和appid未綁定”如何處理?

A:請商戶自行檢查mch_id和appid是否有對應(yīng)的綁定關(guān)系。綁定步驟參考“商家商戶號與AppID賬號關(guān)聯(lián)管理”。



技術(shù)咨詢

文檔反饋