支付寶條碼支付

  最近在作第三方支付功能,其中支付寶用了條碼支付這種高大上的新支付方式,話說還有比較常見的是支付寶掃碼支付,這兩種有什麼區別呢,很簡單,就是掃碼支付是消費者用手機主動掃碼再支付,條碼支付是商家用掃碼槍主動掃碼再支付。那麼爲什麼選擇條碼支付呢,由於這個速度快,從掃消費者手機上的條碼或二維碼,到支付完成,那是瞬間的事,不過要是觸發了須要密碼的時候,仍是須要消費者在手機上輸入支付密碼後才能完成消費的。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

相關文章
相關標籤/搜索