最近在作第三方支付功能,其中支付寶用了條碼支付這種高大上的新支付方式,話說還有比較常見的是支付寶掃碼支付,這兩種有什麼區別呢,很簡單,就是掃碼支付是消費者用手機主動掃碼再支付,條碼支付是商家用掃碼槍主動掃碼再支付。那麼爲什麼選擇條碼支付呢,由於這個速度快,從掃消費者手機上的條碼或二維碼,到支付完成,那是瞬間的事,不過要是觸發了須要密碼的時候,仍是須要消費者在手機上輸入支付密碼後才能完成消費的。html
介紹完了條碼支付後,給個文檔接口吧:支付寶條碼支付。條碼支付整個流程主要須要的API包含:支付接口alipay.trade.pay,查詢訂單接口alipay.trade.query,撤銷訂單接口alipay.trade.cancel,申請退款接口alipay.trade.refund。這些東西都在支付寶提供的SDK裏面包含了,咱們就不用從新造輪子了,支付寶已經提供了很好很強大的SDK了,只是這個生成的dll有點大。web
那麼要想使用這個功能,首先是須要一個支付寶商家帳號的,這個是前置條件。而後須要設置好APPID,這個能夠到這個網址獲取支付寶APPID,獲取好以後,還須要用OPENSSL軟件生成RSA公鑰和私鑰,OPENSSL軟件下載地址我也貼出來吧:OPENSSL的Windows版,32位的和64位的系統均可以用Win32 OpenSSL v1.0.2d Light。安裝完以後先用genrsa -out {0} 1024生成私鑰,其中{0}填私鑰名稱,能夠攜帶絕對路徑,再用rsa -in {0} -pubout -out {1}生成對應的公鑰,其中{0}對應先生成的私鑰,{1}對應要生成的公鑰。生成完以後再到這個網址配置公鑰:配置支付寶公鑰。微信
大體流程就是這樣,如今貼出各API個人調用示例吧:app
/// <summary> /// 扣款 /// </summary> /// <param name="payLog">支付日誌</param> /// <returns></returns> public void Pay(Mall_PayLog payLog) { //參考API列表-條碼支付請求API https://app.alipay.com/market/document.htm?name=tiaomazhifu#page-11 var bizContent = new JsonObject(); //商戶訂單號 bizContent.Put("out_trade_no", payLog.OrderMain.OrderNum); //場景:條碼支付 bizContent.Put("scene", "bar_code"); //條碼 bizContent.Put("auth_code", payLog.Summary); //支付金額 bizContent.Put("total_amount", payLog.Money.ToString("F")); //訂單標題 bizContent.Put("subject", "當面付條碼支付"); //商戶操做員編號 bizContent.Put("operator_id", LoginContext.AuthSession.Emp.RealName); //過時時間,默認5分鐘後自動取消支付 bizContent.Put("time_expire", DateTime.Now.AddMinutes(5).ToString("yyyy-MM-dd HH:mm:ss")); var payRequest = new AlipayTradePayRequest { BizContent = bizContent.ToString() }; var result = GetAopClient(payLog.PayType.PaySetting).Execute(payRequest); switch (result.Code) { //支付成功 case ResultCode.SUCCESS: payLog.IDNum = result.TradeNo; payLog.PayedMoney = payLog.Money; payLog.PayState = Mall_EnumPayLogState.Payed; payLog.Update(); break; //支付中 case ResultCode.INRROCESS: payLog.IDNum = result.TradeNo; payLog.Update(); throw new MallException(ExceptionCode.PAY_PAYING, "請在手機端確認支付"); //支付失敗 default: //payLog.IDNum = result.TradeNo; //payLog.Update(); new Loger().Info(string.Format("支付寶支付失敗,PayLogID:{0},交易號{1},錯誤信息:{2}", payLog.ID, result.TradeNo, result.SubMsg)); throw new MallException(ExceptionCode.PAY_NOTCOMPLETED, "支付寶條碼支付失敗:" + result.SubMsg); } }
/// <summary> /// 服務端查詢支付狀態 /// </summary> /// <returns>0:進行中,1:已完成,2:已取消</returns> public int GetServicePayState(Mall_PayLog payLog) { var bizContent = new JsonObject(); //商戶訂單號(也能夠只傳支付寶交易號trade_no) bizContent.Put("out_trade_no", payLog.OrderMain.OrderNum); var payRequest = new AlipayTradeQueryRequest { BizContent = bizContent.ToString() }; var result = GetAopClient(payLog.PayType.PaySetting).Execute(payRequest); switch (result.Code) { //處理成功 case ResultCode.SUCCESS: if (result.TradeStatus == "TRADE_SUCCESS") { if (payLog.PayState == Mall_EnumPayLogState.Paying) { //更新支付狀態 payLog.PayedMoney = payLog.Money; payLog.PayState = Mall_EnumPayLogState.Payed; payLog.Update(); } return 1; } return 0; default: //備註保存失敗信息 payLog.Summary = result.SubMsg; payLog.Update(); return 2; } }
/// <summary> /// 撤銷支付(撤銷還未支付的付款) /// </summary> /// <param name="payLog"></param> /// <returns></returns> public void ReversePay(Mall_PayLog payLog) { var bizContent = new JsonObject(); //商戶訂單號 bizContent.Put("out_trade_no", payLog.OrderMain.OrderNum); var payRequest = new AlipayTradeCancelRequest { BizContent = bizContent.ToString() }; var result = GetAopClient(payLog.PayType.PaySetting).Execute(payRequest); switch (result.Code) { //撤銷訂單成功 case ResultCode.SUCCESS: break; default: throw new MallException(ExceptionCode.PAY_NOTCOMPLETED, "撤銷訂單失敗:" + result.SubMsg); } }
申請退款:函數
/// <summary> /// 退款 /// </summary> /// <param name="tradeNo">支付寶交易號</param> /// <param name="refundAmount">退款金額</param> /// <param name="appId">支付寶APPID</param> /// <returns></returns> public void RefundPay(string tradeNo, decimal refundAmount, string appId) { if (string.IsNullOrEmpty(tradeNo)) { throw new MallException(ExceptionCode.COMMON_BASE_CODEERROR, "未找到支付寶交易號"); } if (refundAmount < 0) { throw new MallException(ExceptionCode.COMMON_BASE_CODEERROR, "退款金額不能小於0"); } if (string.IsNullOrEmpty(appId)) { throw new MallException(ExceptionCode.COMMON_BASE_CODEERROR, "未找到支付寶AppId"); } var bizContent = new JsonObject(); //支付寶交易號 bizContent.Put("trade_no", tradeNo); //退款金額 bizContent.Put("refund_amount", refundAmount.ToString("F")); //退款緣由 bizContent.Put("refund_reason", "O2O當面付退款"); var payRequest = new AlipayTradeRefundRequest { BizContent = bizContent.ToString() }; var result = GetAopClient(appId).Execute(payRequest); switch (result.Code) { //退款成功 case ResultCode.SUCCESS: break; //退款失敗 default: throw new MallException(ExceptionCode.PAY_NOTCOMPLETED, "退款失敗:" + result.SubMsg); } }
須要特殊處理的是,當須要消費者在手機端輸入支付密鑰時,必須等待消費者輸完密碼完成支付後手動查詢支付的最新狀態,這個也能夠作成自動刷新狀態,我是作成手動刷新的,還有就是密鑰的生成須要四個dll,在安裝的openssl目錄裏找到spa
這四個dll放到你的程序根目錄下就能夠了,而後生成密鑰就用這個函數:日誌
/// <summary> /// 執行OpenSsl命令 /// </summary> /// <param name="commands">命令</param> public void ExecuteOpenSslCommand(params string[] commands) { using (var openssl = new Process { StartInfo = { //設定程序名 FileName = _openSslPath, //關閉Shell的使用 UseShellExecute = false, //重定向標準輸入 RedirectStandardInput = true, //重定向標準輸出 RedirectStandardOutput = true, //重定向錯誤輸出 RedirectStandardError = true, //設置不顯示窗口 CreateNoWindow = true } }) { openssl.Start(); commands.Each(o => openssl.StandardInput.WriteLine(o)); } }
至此,支付寶條碼支付功能就已經介紹完了,其餘支付寶支付的調用也是相似的。以爲不錯請點贊支持我喔,下篇將介紹微信掃碼支付的示例。code