支付寶當面付(條碼支付)功能開發
阿新 • • 發佈:2017-09-08
stream static start his pub -a tree color 結果
商戶可通過以下任一方式在線下完成交易收款:
簡單地說,即我們日常中使用的 條碼支付、掃碼支付、聲波支付。
本篇的開發流程,將以條碼支付為功能開發展開說明,條碼支付即用戶展示付款條碼,商家設定金額後采用掃碼槍(或輸入用戶條碼值)掃描用戶條碼,直接進行扣款,所有操作由商家完成,用戶僅需提供條碼。
使用步驟很簡單:
這兩項是非必需填寫項,根據實際情況來是否配置。
註意:其中密鑰長度為1024的即為RSA(SHA1),長度為2048的即為RSA2(SHA256)
(註意:應用命名不能出現如支付字樣,於是之前我的應用因為名字“猛追灣一卡通條碼支付”被駁回審核了,手動微笑)
顯然,如上所示,涉及三個接口:
接口調用涉及一大堆參數,支付寶倒是也很貼心,直接幫我們做好了相關的SDK(服務端SDK),可以直接調用API,而且對於一些公共參與已經幫我們封裝好了,調用時只需要傳入業務參數即可。
下載好SDK之後,裏面的readme也寫的很明白,集成支付寶接口需要引入的文件是:
在《服務端SDK》中有調用示例如下:
顯然因為SDK封裝得很友好,我們只需要傳入配置參數,設置好業務內容參數,直接調起方法就可以了。下面是我個人的代碼示例:
為了方便將來配置參數的修改,配置直接寫到了配置文件中:
然後做一個類來進行封裝開發者配置,用一個類來封裝業務參數的JSON,再封裝一個工具類以使用。
封裝開發者配置的類:
封裝業務請求參數的類(註意,此處示例僅有部分必要參數,更多參數詳見官方文檔的請求參數部分):
支付工具類和測試代碼:
因為SDK封裝的緣故,所以整體過程很簡單了,對於支付成功後的響應,以及其他支付查詢、支付退款等功能就不再展開了。
但是自己在過程中還是有兩個點覺得有點坑,再次提一下:
1、什麽是當面付
當面付產品介紹商戶可通過以下任一方式在線下完成交易收款:
- 商家通過掃描線下買家支付寶錢包中的條碼、二維碼等方式將買家的交易資金直接打入賣家支付寶賬戶,資金實時到賬;
- 線下買家通過使用支付寶錢包掃描商家的二維碼等方式完成支付,提升商家收銀效率,資金實時到賬;
- 線下買家使用支付寶錢包中的當面付功能,通過聲波支付的方式向商家完成付款,資金實時到賬。
簡單地說,即我們日常中使用的 條碼支付、掃碼支付、聲波支付。
本篇的開發流程,將以條碼支付為功能開發展開說明,條碼支付即用戶展示付款條碼,商家設定金額後采用掃碼槍(或輸入用戶條碼值)掃描用戶條碼,直接進行扣款,所有操作由商家完成,用戶僅需提供條碼。
2、條碼支付業務說明
使用步驟很簡單:
- 用戶登錄支付寶錢包,在首頁點擊“付款”,進入付款碼界面
- 收銀員在商家收銀系統操作生成訂單
- 用戶出示其“付款碼”,收銀員用掃碼設備掃描用戶手機上的條碼(或手動輸入條碼值)後,商家收銀系統提交支付
- 付款後支付寶後臺會返回支付結果給商家,同時將支付情況通知到用戶
3、如何接入條碼支付
官方接入文檔說明:當面付快速接入3.1 創建應用和配置
3.1.1 創建應用
登陸支付寶開放平臺,找到 “ 開發者中心 - 應用 - 創建應用 ”: 創建應用後,選擇支付應用,因為是自己開發自己用,所以選擇自用型應用,名稱自定義:3.1.2 填寫資料和提交審核
功能選項中需要簽約開通“當面付”,提交一些審核資料什麽的,此處不展開。 這部分的說明在官方有詳細文檔《開放平臺應用創建指南》,此處僅對 “開發配置” 作重點說明:3.1.2.1 應用網關 和 授權回調地址
- 應用網關,用於接收支付寶異步通知(比如用戶付款成功了的通知會發送到該地址,口碑開店的門店信息修改也會觸發通知)
- 授權回調地址,即第三方授權或用戶信息授權後回調地址
這兩項是非必需填寫項,根據實際情況來是否配置。
3.1.2.2 應用密鑰RSA2
密鑰的生成在官方有文檔說明《如何生成密鑰》:- 下載Windows版RSA密鑰生成器(Mac版點這裏)
- 根據官方文檔說明進行密鑰生成,此處不再詳細展開
註意:其中密鑰長度為1024的即為RSA(SHA1),長度為2048的即為RSA2(SHA256)
3.1.2.3 提交審核
各項設置完成後,提交審核,審核預計在一個工作日完成,審核完成後,應用狀態會顯示為“已上線”。3.2 條碼支付開發
先看下官方提供的接口調用流程:顯然,如上所示,涉及三個接口:
- 支付 alipay.trade.pay
- 查詢 alipay.trade/query
- 撤銷 alipay.trade.cancel
接口調用涉及一大堆參數,支付寶倒是也很貼心,直接幫我們做好了相關的SDK(服務端SDK),可以直接調用API,而且對於一些公共參與已經幫我們封裝好了,調用時只需要傳入業務參數即可。
下載好SDK之後,裏面的readme也寫的很明白,集成支付寶接口需要引入的文件是:
- alipay-sdk-java*.jar
- commons-logging-1.1.1.jar
在《服務端SDK》中有調用示例如下:
//實例化客戶端
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
//實例化具體API對應的request類,類名稱和接口名稱對應,當前調用接口名稱:alipay.open.public.template.message.industry.modify
AlipayOpenPublicTemplateMessageIndustryModifyRequest request = new AlipayOpenPublicTemplateMessageIndustryModifyRequest();
//SDK已經封裝掉了公共參數,這裏只需要傳入業務參數
//此次只是參數展示,未進行字符串轉義,實際情況下請轉義
request.setBizContent(" {" +
" \"primary_industry_name\":\"IT科技/IT軟件與服務\"," +
" \"primary_industry_code\":\"10001/20102\"," +
" \"secondary_industry_code\":\"10001/20102\"," +
" \"secondary_industry_name\":\"IT科技/IT軟件與服務\"" +
" }");
AlipayOpenPublicTemplateMessageIndustryModifyResponse response = alipayClient.execute(request);
//調用成功,則處理業務邏輯
if(response.isSuccess()){
//.....
}
顯然因為SDK封裝得很友好,我們只需要傳入配置參數,設置好業務內容參數,直接調起方法就可以了。下面是我個人的代碼示例:
為了方便將來配置參數的修改,配置直接寫到了配置文件中:
#應用id,要求應用上線,且其下功能簽約狀態為生效
appId=20110906...78327
#應用私鑰(appId所屬應用的應用私鑰)RSA2加密方式
privateKey=MIIEvgI...oC6/I2xPqZnvhbntS5qi1NwYg2
#支付寶公鑰
alipayPublicKey=MIIBI...wIDAQAB
然後做一個類來進行封裝開發者配置,用一個類來封裝業務參數的JSON,再封裝一個工具類以使用。
封裝開發者配置的類:
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 支付寶API類
*/
public class AlipayAPI {
/** 應用ID */
private static String appId;
/** 應用私鑰 */
private static String privateKey;
/** 支付寶公鑰 */
private static String alipayPublicKey;
/** 支付調用接口 */
private static final String url_pay = "https://openapi.alipay.com/gateway.do";
static {
InputStream is = AlipayAPI.class.getResourceAsStream("/alipay.properties");
Properties prop = new Properties();
try {
prop.load(is);
setAppId(prop.getProperty("appId"));
setPrivateKey(prop.getProperty("privateKey"));
setAlipayPublicKey(prop.getProperty("alipayPublicKey"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static String getAppId() {
return appId;
}
public static void setAppId(String appId) {
AlipayAPI.appId = appId;
}
public static String getPrivateKey() {
return privateKey;
}
public static void setPrivateKey(String privateKey) {
AlipayAPI.privateKey = privateKey;
}
public static String getAlipayPublicKey() {
return alipayPublicKey;
}
public static void setAlipayPublicKey(String alipayPublicKey) {
AlipayAPI.alipayPublicKey = alipayPublicKey;
}
public static String getUrl_pay() {
return url_pay;
}
}
封裝業務請求參數的類(註意,此處示例僅有部分必要參數,更多參數詳見官方文檔的請求參數部分):
/**
* 統一收單交易支付的參數封裝類
*/
public class PayParam {
/** 商戶訂單 */
private String out_trade_no;
/** 支付場景 */
private String scene;
/** 支付授權碼,即用戶的付款碼 */
private String auth_code;
/** 訂單標題 */
private String subject;
/** 訂單金額 */
private double total_amount;
public PayParam(String out_trade_no, String subject, double total_amount, String auth_code) {
this.out_trade_no = out_trade_no;
this.subject = subject;
this.total_amount = total_amount;
this.auth_code = auth_code;
}
public String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getScene() {
return scene;
}
public void setScene(String scene) {
this.scene = scene;
}
public String getAuth_code() {
return auth_code;
}
public void setAuth_code(String auth_code) {
this.auth_code = auth_code;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public double getTotal_amount() {
return total_amount;
}
public void setTotal_amount(double total_amount) {
this.total_amount = total_amount;
}
}
支付工具類和測試代碼:
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.response.AlipayTradePayResponse;
import java.util.Date;
/**
* 支付寶的工具類
*/
public class AlipayUtil {
/** UTF8編碼格式 */
private static final String CHARSET_UTF8 = "UTF-8";
/** 加密方式 */
private static final String SIGN_TYPE = "RSA2";
/** 數據格式 */
private static final String FORMAT = "JSON";
/** 支付場景,條碼支付 */
private static final String SCENE_BARCODE = "bar_code";
/**
* 當面付(條碼支付)
* @param content
* @return
*/
public static AlipayTradePayResponse barCodePay(PayParam content){
AlipayClient client = new DefaultAlipayClient(AlipayAPI.getUrl_pay(), AlipayAPI.getAppId(),
AlipayAPI.getPrivateKey(), FORMAT, CHARSET_UTF8, AlipayAPI.getAlipayPublicKey(), SIGN_TYPE);
AlipayTradePayRequest request = new AlipayTradePayRequest();
content.setScene(SCENE_BARCODE);
String bizContent = JSON.toJSONString(content);
request.setBizContent(bizContent);
AlipayTradePayResponse response = null;
try {
response = client.execute(request);
} catch (AlipayApiException e) {
e.printStackTrace();
}
return response;
}
/**
* 支付完成後的業務處理
* @param response
*/
public static void afterBarCodePay(AlipayTradePayResponse response) {
if (response.isSuccess()) {
//處理業務邏輯
System.out.println("start handle business");
}
}
/**
* 獲取商戶訂單
* @return
*/
public static String getTradeNo() {
return "PAY" + new Date().getTime();
}
//測試
public static void main(String[] args) {
String tradeNo = getTradeNo();
String subject = "測試用訂單";
double totalAmount = 0.01;
String authCode = "274726044141298157";
PayParam param = new PayParam(tradeNo, subject, totalAmount, authCode);
AlipayTradePayResponse response = barCodePay(param);
System.out.println(response.getBody());
afterBarCodePay(response);
}
}
因為SDK封裝的緣故,所以整體過程很簡單了,對於支付成功後的響應,以及其他支付查詢、支付退款等功能就不再展開了。
但是自己在過程中還是有兩個點覺得有點坑,再次提一下:
- 創建AlipayClient對象的傳參中,公鑰是支付寶公鑰,而不是應用公鑰
- 服務端SDK的示例中請求調用的類是AlipayOpenPublicTemplateMessageIndustryModifyResponse,實際條碼支付的請求類應該調用AlipayTradePayRequest
4、參考鏈接
- 支付寶掃碼支付(當面付)開發流程
- 支付寶支付-刷卡支付(條碼支付)
附件列表
支付寶當面付(條碼支付)功能開發