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

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

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

1. 接口規(guī)則

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

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

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

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

測(cè)試步驟

1、根據(jù)自身開發(fā)語言,選擇對(duì)應(yīng)的開發(fā)庫(kù)并構(gòu)建項(xiàng)目,具體配置請(qǐ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)建加載商戶私鑰、加載平臺(tái)證書、初始化httpClient的通用方法


@Before
public void setup() throws IOException {
    // 加載商戶私鑰(privateKey:私鑰字符串)
    PrivateKey merchantPrivateKey = PemUtil
            .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
 
    // 加載平臺(tái)證書(mchId:商戶號(hào),mchSerialNo:商戶證書序列號(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;
 
// 商戶相關(guān)配置,
$merchantId = '1000100'; // 商戶號(hào)
$merchantSerialNumber = 'XXXXXXXXXX'; // 商戶API證書序列號(hào)
$merchantPrivateKey = PemUtil::loadPrivateKey('./path/to/mch/private/key.pem'); // 商戶私鑰文件路徑
 
// 微信支付平臺(tái)配置
$wechatpayCertificate = PemUtil::loadCertificate('./path/to/wechatpay/cert.pem'); // 微信支付平臺(tái)證書文件路徑
 
// 構(gòu)造一個(gè)WechatPayMiddleware
$wechatpayMiddleware = WechatPayMiddleware::builder()
    ->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 傳入商戶相關(guān)配置
    ->withWechatPay([ $wechatpayCertificate ]) // 可傳入多個(gè)微信支付平臺(tái)證書,參數(shù)類型為array
    ->build();
 
// 將WechatPayMiddleware添加到Guzzle的HandlerStack中
$stack = GuzzleHttp\HandlerStack::create();
$stack->push($wechatpayMiddleware, 'wechatpay');
 
// 創(chuàng)建Guzzle HTTP Client時(shí),將HandlerStack傳入,接下來,正常使用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ù),你可以使用它來創(chuàng)建一個(gè)client,并向微信支付發(fā)送http請(qǐng)求
    只需要你在初始化客戶端的時(shí)候,傳遞credential以及validator
    credential用來生成http header中的authorization信息
    validator則用來校驗(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ào)
    mchID := ""
    //商戶證書序列號(hào)
    mchCertSerialNumber := ""
    //商戶私鑰文件路徑
    privateKeyPath := ""
    //平臺(tái)證書文件路徑
    wechatCertificatePath := ""

    // 加載商戶私鑰
    privateKey, err := utils.LoadPrivateKeyWithPath(privateKeyPath)
    if err != nil {
        log.Printf("load private err:%s", err.Error())
        return nil, err
    }
    // 加載微信支付平臺(tái)證書
    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è)置微信支付平臺(tái)證書,用于校驗(yàn)回包信息用
    }
    return opts, nil
}

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

說明:

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

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

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

    1.簽名生成

    2.簽名驗(yàn)證

    3.敏感信息加解密

    4.merchantPrivateKey(私鑰)

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

    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、測(cè)試白名單、免確認(rèn)訂單模式的權(quán)限等。

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


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

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

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

步驟1 用戶在商戶側(cè)下單購(gòu)買產(chǎn)品或服務(wù),此時(shí),我們需要先對(duì)用戶的授權(quán)狀態(tài)進(jìn)行查詢

查詢用戶授權(quán)狀態(tài)的兩種方法:

用戶授權(quán)狀態(tài)一共分三種:
UNAVAILABLE:用戶未授權(quán)服務(wù)
AVAILABLE:用戶已授權(quán)服務(wù)
UNBINDUSER:未綁定用戶

當(dāng)查詢到用戶授權(quán)狀態(tài)為UNAVAILABLE、UNBINDUSER時(shí),請(qǐng)前往步驟二:引導(dǎo)用戶開啟服務(wù);

當(dāng)查詢到用戶授權(quán)狀態(tài)為AVAILABLE時(shí),請(qǐng)前往步驟三:創(chuàng)建支付分訂單;


步驟2 引導(dǎo)用戶開啟授權(quán)服務(wù)

開啟授權(quán)有兩步操作,第一步:調(diào)用后臺(tái)接口進(jìn)行預(yù)授權(quán),第二步:調(diào)用前端方法跳轉(zhuǎn)進(jìn)入微信中讓用戶進(jìn)行授權(quán)。

請(qǐng)求開啟授權(quán)之后,我們需要確認(rèn)開啟授權(quán)是否成功,共有兩種方法:

1、通過接口主動(dòng)查詢(未及時(shí)收到用戶授權(quán)成功通知情況下且用戶已回到商家授權(quán)頁(yè)面時(shí)商戶側(cè)主動(dòng)查詢。)——查詢與用戶授權(quán)記錄(openid)查詢與用戶授權(quán)記錄(授權(quán)協(xié)議號(hào))

2、等待支付分的異步通知——開啟/解除授權(quán)結(jié)果回調(diào)通知

若獲取到用戶的授權(quán)狀態(tài)為AVAILABLE:用戶已授權(quán)服務(wù),則前往步驟三;

若獲取到用戶的授權(quán)狀態(tài)為UNAVAILABLE-用戶未授權(quán)服務(wù)、UNBINDUSER-未綁定用戶,則商戶可根據(jù)業(yè)務(wù)需要選擇繼續(xù)查詢或者結(jié)束支付分流程,進(jìn)入商戶自己的業(yè)務(wù)流程。


步驟3 創(chuàng)建支付分訂單

我們通過創(chuàng)建支付分訂單API接口創(chuàng)建一筆待支付的支付分訂單。

請(qǐng)求:

入?yún)ⅰ皀eed_user_confirm”,取值請(qǐng)選擇 “false”;

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

返回:

  • 若接口返回state=DOING:表示商戶創(chuàng)建服務(wù)訂單成功,可前往步驟四;
  • 若接口返回state≠DOING:表示商戶創(chuàng)建服務(wù)訂單失敗,商戶可根據(jù)實(shí)際返回內(nèi)容提示選擇重新創(chuàng)建或者結(jié)束支付分流程,進(jìn)入商戶自己的業(yè)務(wù)流程;

     創(chuàng)建服務(wù)訂單失敗原因會(huì)在接口返回字段“message”中返回,主要失敗原因有兩種:
         1、存在未完結(jié)訂單
         2、綜合評(píng)估不通過,建議商戶稍后重試或者使用其他渠道支付


步驟4 商戶為用戶提供服務(wù),待服務(wù)結(jié)束后,商戶調(diào)用完結(jié)訂單接口完結(jié)當(dāng)前訂單。

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

請(qǐ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接口主動(dòng)查詢扣款情況。

  • 如訂單狀態(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.主動(dòng)查單,通過查詢支付分訂單API 接口主動(dòng)查詢扣款情況

2.次日對(duì)賬,通過申請(qǐng)交易賬單API接口申請(qǐng)交易賬單,再通過后臺(tái)接口下載賬單API下載交易賬單


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

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

注意:

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

步驟說明:創(chuàng)建支付分訂單的前提是用戶必須有授權(quán)關(guān)系,所以在免確認(rèn)模式下,我們最先要做的就是確保用戶是已授權(quán)狀態(tài)。目前提供了使用openid授權(quán)協(xié)議號(hào)兩種條件進(jìn)行查詢的方式。下面以查詢與用戶授權(quán)記錄(openid)舉例接口調(diào)用方式。

示例代碼

public void GetPermissionsByOpenid() throws Exception{

  //請(qǐng)求URL
  HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/payscore/permissions/openid/{openid}");
  httpGet.setHeader("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) { //處理成功,無返回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/permissions/openid/{openid}', //請(qǐng)求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)行錯(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明

? 查詢條件參數(shù)openid或者授權(quán)協(xié)議號(hào)都是在接口url中傳遞的,請(qǐng)勿傳到body中去。

更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見查詢與用戶授權(quán)記錄(openid)接口文檔

3.2.2.【服務(wù)端】請(qǐng)求預(yù)授權(quán)接口

步驟說明:創(chuàng)建支付分訂單的前提是用戶必須有授權(quán)關(guān)系,所以在免確認(rèn)模式下,我們最先要做的就是確保用戶是已授權(quán)狀態(tài)。通過商戶預(yù)授權(quán)接口獲取跳轉(zhuǎn)用戶授權(quán)頁(yè)必填參數(shù)“預(yù)授權(quán)token”。

示例代碼

public void permissions() throws Exception{
//請(qǐng)求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/permissions");
// 請(qǐng)求body參數(shù)
String reqdata = "{"
        + "\"service_id\":\"500001\","
        + "\"appid\":\"wxd678efh567hg6787\","
        + "\"authorization_code\":\"1234323JKHDFE1243252\","
        + "\"notify_url\":\"http://www.qq.com\""
        + "}";
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) { //處理成功,無返回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/permissions', //請(qǐng)求URL
    [
        // JSON請(qǐng)求體
        'json' => [
            "service_id" => "500001",
            "appid" => "wxd678efh567hg6787",
            "authorization_code" => "1234323JKHDFE1243252",
            "notify_url" => "http://www.qq.com",
        ],
        '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)行錯(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明

? 完成用戶授權(quán)需要兩步操作,預(yù)授權(quán)接口僅是為獲取關(guān)鍵參數(shù)“預(yù)授權(quán)token”,商戶還需引導(dǎo)用戶跳轉(zhuǎn)到微信授權(quán)頁(yè)進(jìn)行授權(quán)操作。

更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見 商戶預(yù)授權(quán)API接口文檔

3.2.3.【客戶端】開啟授權(quán)服務(wù)

步驟說明:通過商戶預(yù)授權(quán)接口獲取到跳轉(zhuǎn)用戶授權(quán)頁(yè)必填參數(shù)“預(yù)授權(quán)token”后,即可通過前端方法跳轉(zhuǎn)到微信客戶端,讓用戶開啟授權(quán)服務(wù)。前端跳轉(zhuǎn)方法請(qǐng)根據(jù)用戶實(shí)際使用場(chǎng)景(APP、小程序、微信內(nèi)H5)來選擇。

3.2.4. 【服務(wù)端】開啟/解除授權(quán)服務(wù)回調(diào)通知

步驟說明:當(dāng)用戶授權(quán)或解約服務(wù)成功時(shí),微信會(huì)把相關(guān)信息異步回調(diào)的方式通知商戶,商戶需要接收處理,并按文檔規(guī)范返回應(yīng)答

注意:

  • 支付結(jié)果通知是以POST 方法訪問商戶設(shè)置的通知url,通知的數(shù)據(jù)以JSON 格式通過請(qǐng)求主體(BODY)傳輸。通知的數(shù)據(jù)包括了加密的支付結(jié)果詳情
  • 加密不能保證通知請(qǐng)求來自微信。微信會(huì)對(duì)發(fā)送給商戶的通知進(jìn)行簽名,并將簽名值放在通知的HTTP頭Wechatpay-Signature。商戶應(yīng)當(dāng)驗(yàn)證簽名,以確認(rèn)請(qǐng)求來自微信,而不是其他的第三方。簽名驗(yàn)證的算法請(qǐng)參考 《微信支付API v3簽名驗(yàn)證》
  • 支付通知http應(yīng)答碼為200或204才會(huì)當(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
  • 同樣的通知可能會(huì)多次發(fā)送給商戶系統(tǒng)。商戶系統(tǒng)必須能夠正確處理重復(fù)的通知。 推薦的做法是,當(dāng)商戶系統(tǒng)收到通知進(jìn)行處理時(shí),先檢查對(duì)應(yīng)業(yè)務(wù)數(shù)據(jù)的狀態(tài),并判斷該通知是否已經(jīng)處理。如果未處理,則再進(jìn)行處理;如果已處理,則直接返回結(jié)果成功。在對(duì)業(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)詳情及錯(cuò)誤碼請(qǐng)參見開啟/解除授權(quán)服務(wù)回調(diào)通知API接口文檔


3.2.5. 【服務(wù)端】創(chuàng)建支付分訂單

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

示例代碼

public void CreateServiceOrder() throws Exception{

    //請(qǐng)求URL
    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/serviceorder");
    // 請(qǐng)求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í)行請(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) { //處理成功,無返回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', //請(qǐng)求URL
      [
          // JSON請(qǐng)求體
          '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)行錯(cuò)誤處理
  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”,取值請(qǐng)選擇 “false”;
  • 入?yún)ⅰ皉isk_fund:name”,取值請(qǐng)選擇【先享模式】中的枚舉值。

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

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

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

示例代碼


public void CompleteServiceOrder() throws Exception{

  //請(qǐng)求URL
  HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/serviceorder/{out_order_no}/complete");
  // 請(qǐng)求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í)行請(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) { //處理成功,無返回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', //請(qǐng)求URL
        [
            // JSON請(qǐng)求體
            '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)行錯(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é)支付分訂單API接口文檔


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

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

示例代碼

public void ModifyServiceOrder() throws Exception{

    //請(qǐng)求URL
    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/serviceorder/{out_order_no}/modify");
    // 請(qǐng)求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í)行請(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) { //處理成功,無返回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', //請(qǐng)求URL
        [
            // JSON請(qǐng)求體
            '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)行錯(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)參見修改訂單金額API接口文檔


3.2.8【服務(wù)端】取消支付分訂單

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

示例代碼

public void CancelServiceOrder() throws Exception{

    //請(qǐng)求URL
    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/serviceorder/{out_order_no}/cancel");
    // 請(qǐng)求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í)行請(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) { //處理成功,無返回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', //請(qǐng)求URL
        [
            // JSON請(qǐng)求體
            '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)行錯(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)參見取消支付分訂單API接口文檔


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

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

示例代碼

public void SyncServiceOrder() throws Exception{
//請(qǐng)求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/serviceorder/{out_order_no}/sync");
// 請(qǐng)求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í)行請(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) { //處理成功,無返回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', //請(qǐng)求URL
    [
        // JSON請(qǐng)求體
        '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)行錯(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)參見 同步服務(wù)訂單信息API接口文檔


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

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

示例代碼

public void GetServiceOrder() throws Exception{

  //請(qǐng)求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í)行請(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) { //處理成功,無返回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', //請(qǐng)求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)行錯(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)參見 查詢支付分訂單API接口文檔


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

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

示例代碼

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->getBody()->getContents()."\n";
} else if ($statusCode == 204) { //處理成功,無返回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)參見 申請(qǐng)交易賬單API接口文檔


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

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

示例代碼

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();
  
//請(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->getBody()->getContents()."\n";
} else if ($statusCode == 204) { //處理成功,無返回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)烈建議商戶將實(shí)際賬單文件的哈希值和之前從接口獲取到的哈希值進(jìn)行比對(duì),以確認(rèn)數(shù)據(jù)的完整性

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


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

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

注意:

  • 支付結(jié)果通知是以POST 方法訪問商戶設(shè)置的通知url,通知的數(shù)據(jù)以JSON 格式通過請(qǐng)求主體(BODY)傳輸。通知的數(shù)據(jù)包括了加密的支付結(jié)果詳情
  • 加密不能保證通知請(qǐng)求來自微信。微信會(huì)對(duì)發(fā)送給商戶的通知進(jìn)行簽名,并將簽名值放在通知的HTTP頭Wechatpay-Signature。商戶應(yīng)當(dāng)驗(yàn)證簽名,以確認(rèn)請(qǐng)求來自微信,而不是其他的第三方。簽名驗(yàn)證的算法請(qǐng)參考 《微信支付API v3簽名驗(yàn)證》
  • 支付通知http應(yīng)答碼為200或204才會(huì)當(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
  • 同樣的通知可能會(huì)多次發(fā)送給商戶系統(tǒng)。商戶系統(tǒng)必須能夠正確處理重復(fù)的通知。 推薦的做法是,當(dāng)商戶系統(tǒng)收到通知進(jìn)行處理時(shí),先檢查對(duì)應(yīng)業(yè)務(wù)數(shù)據(jù)的狀態(tài),并判斷該通知是否已經(jīng)處理。如果未處理,則再進(jìn)行處理;如果已處理,則直接返回結(jié)果成功。在對(duì)業(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)詳情及錯(cuò)誤碼請(qǐng)參見 支付成功回調(diào)通知API接口文檔


3.2.14【服務(wù)端】解除用戶授權(quán)關(guān)系

步驟說明:如果用戶或者商戶有解除授權(quán)關(guān)系的需求,可通過該接口進(jìn)行“解約”。我們提供了兩種解約方式:使用簽約協(xié)議號(hào)和使用用戶openid進(jìn)行解約,下面我們以使用用戶openid解約為例,進(jìn)行代碼演示。

更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見 解除用戶授權(quán)關(guān)系A(chǔ)PI接口文檔


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

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

4. 常見問題

Q:商戶小程序跳轉(zhuǎn)支付分小程序(詳情頁(yè),授權(quán)頁(yè))報(bào)錯(cuò)“未通過申請(qǐng),當(dāng)前服務(wù)未上線”

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

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

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

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

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

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

Q:免確認(rèn)訂單模式創(chuàng)建支付分訂單報(bào)錯(cuò){"code":"INVALID_REQUEST","message":"綜合評(píng)估不通過"}是什么原因

A:表示免確認(rèn)流程創(chuàng)單用戶被不對(duì)外風(fēng)控?cái)r截

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

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



技術(shù)咨詢

文檔反饋