1 企業轉賬Demo
1.1 pingpp–java
在下載的ping++ sdk中找到TransferExample複製到你的項目中
1.2 運行前將你的ip配置到白名單
1.3 替換參數(以銀聯轉賬爲例)
/* *
* Ping++ Server SDK
* 說明:
* 以下代碼只是爲了方便商戶測試而提供的樣例代碼,商戶可根據自己網站需求按照技術文檔編寫, 並非一定要使用該代碼。
* 接入企業付款流程參考開發者中心:https://www.pingxx.com/docs/server/transfer ,文檔可篩選後端語言和接入渠道。
* 該代碼僅供學習和研究 Ping++ SDK 使用,僅供參考。
*/
package com.omlife.pay.common;
import com.pingplusplus.Pingpp;
import com.pingplusplus.exception.*;
import com.pingplusplus.model.Transfer;
import com.pingplusplus.model.TransferCollection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
*
* 該實例演示如何使用 Ping++ 進行企業轉賬。
*
* 開發者需要填寫 apiKey ,openid 和 appId ,
*
* apiKey 有 TestKey 和 LiveKey 兩種。
*
* TestKey 模式下不會產生真實的交易。
*
* openid 是發送紅包的對象在公共平臺下的 openid ,獲得 openid 的方法可以參考微信文檔:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
*
*/
public class TransferExample {
public static void main(String[] args) throws Exception {
runDemos("你的appId"); // 運行這個即可
}
private String appId;
/**
* 接收者的 openid
*/
public static String openid = "USER_OPENID"; // 用戶在商戶微信公衆號下的唯一標識,獲取方式可參考 WxPubOAuthExample.java
public static void runDemos(String appId) {
// ping++ appId
Pingpp.appId = "你的appId";
// Secret Key
Pingpp.apiKey = "你的"Secret Key;
// 你的私鑰位置
Pingpp.privateKeyPath = "D:\\Project\\service\\src\\main\\resources\\keys\\rsa_private_key.pem";
TransferExample transferExample = new TransferExample(appId);
System.out.println("------- 創建 Transfer -------");
Transfer transfer = transferExample.create1();
System.out.println("------- 查詢 Transfer -------");
transferExample.retrieve(transfer.getId());
System.out.println("------- 查詢 Transfer 列表 -------");
transferExample.list();
}
TransferExample(String appId) {
this.appId = appId;
}
Transfer create1(){
Map<String, Object> transferMap = new HashMap<String, Object>();
// 銀聯電子代付
transferMap.put("channel", "unionpay");
transferMap.put("order_no", "123456779");
//訂單總金額, 人民幣單位:分(如訂單總金額爲 1 元,此處請填 100)
transferMap.put("amount", 100);
transferMap.put("type", "b2c");
transferMap.put("currency", "cny");
transferMap.put("description", "Your Description");
Map<String, String> app = new HashMap<String, String>();
app.put("id", "app_94e9e9KinHGSDuf1");
transferMap.put("app", app);
Map<String, Object> extra = new HashMap<String, Object>();
extra.put("card_number", "6225220317083517");
extra.put("user_name", "User Name");
extra.put("open_bank_code", "0102");
transferMap.put("extra", extra);
Transfer transfer = null;
try {
transfer = Transfer.create(transferMap);
} catch (Exception e) {
e.printStackTrace();
}
return transfer;
}
/**
* 創建企業轉賬
*
* 創建企業轉賬需要傳遞一個 map 給 Transfer.create();
* map 填寫的具體介紹可以參考:https://www.pingxx.com/api#api-t-new
*
* @return
*/
public Transfer create() {
Transfer transfer = null;
String channel = "alipay";
String orderNo = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
Map<String, Object> transferMap = new HashMap<String, Object>();
transferMap.put("channel", channel); // 目前支持 支付寶:alipay,銀聯:unionpay,微信公衆號:wx_pub,通聯:allinpay,京東:jdpay
// 付款使用的商戶內部訂單號。
// wx_pub 規定爲 1 ~ 50 位不能重複的數字字母組合;
// alipay 爲 1 ~ 64 位不能重複的數字字母組合;
// unionpay 爲 1 ~ 16 位的純數字;
// jdpay 限長 1 ~ 64 位不能重複的數字字母組合;
// allinpay 限長 20 ~ 40 位不能重複的數字字母組合,必須以簽約的通聯的商戶號開頭(建議組合格式:通聯商戶號 + 時間戳 + 固定位數順序流水號,不包含+號)
if (channel == "allinpay") {
orderNo += System.currentTimeMillis();
}
transferMap.put("order_no", orderNo);
transferMap.put("amount", 200); // 付款金額,相關渠道的限額,請查看 https://help.pingxx.com/article/133366/ 。單位爲對應幣種的最小貨幣單位,例如:人民幣爲分。
transferMap.put("type", "b2c"); // 付款類型,轉賬到個人用戶爲 b2c,轉賬到企業用戶爲 b2b(微信公衆號 wx_pub 的企業付款,僅支持 b2c)。
transferMap.put("currency", "cny");
transferMap.put("recipient", channelRecipient(channel)); // 接收者
// 備註信息。
// 渠道爲 unionpay 時,最多 99 個 Unicode 字符;
// 渠道爲 wx_pub 時,最多 99 個英文和數字的組合或最多 33 箇中文字符,不可以包含特殊字符;
// 渠道爲 alipay 時,最多 100 個 Unicode 字符。
// 渠道爲 jdpay 最多100個 Unicode 字符。
// 渠道爲 allinpay 最多30個 Unicode 字符
transferMap.put("description", "your description");
transferMap.put("extra", channelExtra(channel));
Map<String, String> app = new HashMap<String, String>();
app.put("id", appId);
transferMap.put("app", app);
try {
transfer = Transfer.create(transferMap);
System.out.println(transfer);
} catch (AuthenticationException e) {
e.printStackTrace();
} catch (InvalidRequestException e) {
e.printStackTrace();
} catch (APIConnectionException e) {
e.printStackTrace();
} catch (APIException e) {
e.printStackTrace();
} catch (ChannelException e) {
e.printStackTrace();
} catch (RateLimitException e) {
e.printStackTrace();
}
return transfer;
}
/**
* 根據 ID 查詢
*
* 根據 ID 查詢企業轉賬記錄。
* 參考文檔:https://www.pingxx.com/api#api-t-inquiry
* @param id
*/
public void retrieve(String id) {
Map<String, Object> param = new HashMap<String, Object>();
try {
Transfer transfer = Transfer.retrieve(id, param);
System.out.println(transfer);
} catch (AuthenticationException e) {
e.printStackTrace();
} catch (InvalidRequestException e) {
e.printStackTrace();
} catch (APIConnectionException e) {
e.printStackTrace();
} catch (APIException e) {
e.printStackTrace();
} catch (ChannelException e) {
e.printStackTrace();
} catch (RateLimitException e) {
e.printStackTrace();
}
}
/**
* 批量查詢
*
* 批量查詢企業轉賬記錄,默認一次查詢 10 條,用戶可以使用 limit 自定義查詢數目,但是最多不超過 100 條。
*/
public void list() {
Map<String, Object> param = new HashMap<String, Object>();
param.put("limit", 3);
param.put("app[id]", appId);
try {
TransferCollection transferCollection = Transfer.list(param);
System.out.println(transferCollection);
} catch (AuthenticationException e) {
e.printStackTrace();
} catch (InvalidRequestException e) {
e.printStackTrace();
} catch (APIConnectionException e) {
e.printStackTrace();
} catch (APIException e) {
e.printStackTrace();
} catch (ChannelException e) {
e.printStackTrace();
} catch (RateLimitException e) {
e.printStackTrace();
}
}
private String channelRecipient(String channel) {
String recipient = null;
switch (channel) {
case "wx_pub":
// 渠道爲 wx_pub 時,需要傳 recipient 爲用戶在商戶 appid 下的 open_id
recipient = "o7xEMsySBFG3MVHI-9VsAJX-j50W";
break;
case "alipay":
// 渠道爲 alipay 時,若 type 爲 b2c,爲個人支付寶賬號,若 type 爲 b2b,爲企業支付寶賬號。
recipient = "[email protected]";
break;
case "unionpay":
case "allinpay":
case "jdpay":
break;
}
return recipient;
}
private Map<String, Object> channelExtra(String channel) {
Map<String, Object> extra = new HashMap<>();
switch (channel) {
case "alipay":
extra = alipayExtra();
break;
case "wx_pub":
extra = wxPubExtra();
break;
case "unionpay":
extra = unionpayExtra();
break;
case "allinpay":
extra = allinpayExtra();
break;
case "jdpay":
extra = jdpayExtra();
break;
}
return extra;
}
private Map<String, Object> alipayExtra() {
Map<String, Object> extra = new HashMap<>();
// 必須,收款人姓名,1~50位。
extra.put("recipient_name", "張三");
// 可選,收款方賬戶類型。可取值:1、 ALIPAY_USERID :支付寶賬號對應的支付寶唯一用戶號。以2088開頭的16位純數字組成。 2、 ALIPAY_LOGONID (默認值):支付寶登錄號,支持郵箱和手機號格式。
// extra.put("recipient_account_type", "ALIPAY_LOGONID");
return extra;
}
private Map<String, Object> wxPubExtra() {
Map<String, Object> extra = new HashMap<>();
// 可選,收款人姓名。當該參數爲空,則不校驗收款人姓名。
// extra.put("user_name", "張三");
// 可選,是否強制校驗收款人姓名。僅當 user_name 參數不爲空時該參數生效。
// extra.put("force_check", true);
return extra;
}
private Map<String, Object> unionpayExtra() {
Map<String, Object> extra = new HashMap<>();
// 必須,1~32位,收款人銀行卡號或者存摺號。
extra.put("card_number", "6228480402564890011");
// 必須,1~100位,收款人姓名。
extra.put("user_name", "張三");
/**
* open_bank_code 和 open_bank 兩個參數必傳一個,建議使用 open_bank_code ,若都傳參則優先使用 open_bank_code 讀取規則;prov 和 city 均爲可選參數,如果不傳參,則使用默認值 "上海" 給渠道接口。
*/
// 條件可選,4位,開戶銀行編號,詳情請參考 企業付款(銀行卡)銀行編號說明:https://www.pingxx.com/api#%E9%93%B6%E8%A1%8C%E7%BC%96%E5%8F%B7%E8%AF%B4%E6%98%8E。
extra.put("open_bank_code", "0103");
// 條件可選,1~50位,開戶銀行,詳情請參考 企業付款(銀行卡)銀行編號說明:https://www.pingxx.com/api#%E9%93%B6%E8%A1%8C%E7%BC%96%E5%8F%B7%E8%AF%B4%E6%98%8E。
extra.put("open_bank", "農業銀行");
// 可選,1~20位,省份。
// extra.put("prov", "上海");
// 可選,1~40位,城市。
// extra.put("city", "上海");
// 可選,1~80位,開戶支行名稱。
// extra.put("sub_bank", "上海陸家嘴支行");
return extra;
}
private Map<String, Object> allinpayExtra() {
Map<String, Object> extra = new HashMap<>();
// 必須,1~32位,收款人銀行卡號或者存摺號。
extra.put("card_number", "6228480402564890011");
// 必須,1~100位,收款人姓名。
extra.put("user_name", "張三");
// 必須,4位,開戶銀行編號,詳情請參考 企業付款(銀行卡)銀行編號說明:https://www.pingxx.com/api#%E9%93%B6%E8%A1%8C%E7%BC%96%E5%8F%B7%E8%AF%B4%E6%98%8E。
extra.put("open_bank_code", "0103");
// 可選,5位,業務代碼,根據通聯業務人員提供,不填使用通聯提供默認值09900。
// extra.put("business_code", "09900");
// 可選,1位,銀行卡號類型,0:銀行卡、1:存摺,不填默認使用銀行卡。
// extra.put("card_type", 0);
return extra;
}
private Map<String, Object> jdpayExtra() {
Map<String, Object> extra = new HashMap<>();
// 必須,1~32位,收款人銀行卡號或者存摺號。
extra.put("card_number", "6228480402564890011");
// 必須,1~100位,收款人姓名。
extra.put("user_name", "張三");
// 必須,4位,開戶銀行編號,詳情請參考 企業付款(銀行卡)銀行編號說明:https://www.pingxx.com/api#%E9%93%B6%E8%A1%8C%E7%BC%96%E5%8F%B7%E8%AF%B4%E6%98%8E。
extra.put("open_bank_code", "0103");
return extra;
}
}
1.4 運行結果
------- 創建 Transfer -------
------- 查詢 Transfer -------
{
"id": "tr_qLOaHKDinnT8a5uzn5z1q5qH",
"object": "transfer",
"type": "b2c",
"created": 1576804656,
"time_transferred": null,
"livemode": false,
"status": "scheduled",
"app": "app_94e9e9Kin1",
"channel": "unionpay",
"order_no": "123456779",
"amount": 100,
"amount_settle": 100,
"currency": "cny",
"recipient": "6225220317083517",
"description": "Your Description",
"failure_msg": null,
"transaction_no": null,
"extra": {
"open_bank_code": "0102",
"card_number": "6225220317083517",
"user_name": "User Name"
},
"metadata": {}
}
------- 查詢 Transfer 列表 -------
{
"object": "list",
"url": "/v1/transfers",
"has_more": false,
"data": [
{
"id": "tr_GCO4yTLib1K8qL88a9e5Smj5",
"object": "transfer",
"type": "b2c",
"created": 1576744952,
"time_transferred": 1576744955,
"livemode": false,
"status": "paid",
"app": "app_94e9e9HDuf1",
"channel": "unionpay",
"order_no": "123456789",
"amount": 100,
"amount_settle": 100,
"currency": "cny",
"recipient": "6225220317083517",
"description": "Your Description",
"failure_msg": null,
"transaction_no": "426885",
"extra": {
"open_bank_code": "0102",
"card_number": "6225220317083517",
"user_name": "User Name"
},
"metadata": {}
}
]
}