zoukankan      html  css  js  c++  java
  • 支付宝条码支付

      最近在做第三方支付功能,其中支付宝用了条码支付这种高大上的新支付方式,话说还有比较常见的是支付宝扫码支付,这两种有什么区别呢,很简单,就是扫码支付是消费者用手机主动扫码再支付,条码支付是商家用扫码枪主动扫码再支付。那么为何选择条码支付呢,因为这个速度快,从扫消费者手机上的条码或二维码,到支付完成,那是瞬间的事,不过要是触发了需要密码的时候,还是需要消费者在手机上输入支付密码后才能完成消费的。

      介绍完了条码支付后,给个文档接口吧:支付宝条码支付。条码支付整个流程主要需要的API包含:支付接口alipay.trade.pay,查询订单接口alipay.trade.query,撤销订单接口alipay.trade.cancel,申请退款接口alipay.trade.refund。这些东西都在支付宝提供的SDK里面包含了,我们就不用重新造轮子了,支付宝已经提供了很好很强大的SDK了,只是这个生成的dll有点大。

      那么要想使用这个功能,首先是需要一个支付宝商家账号的,这个是前置条件。然后需要设置好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我的调用示例吧:

      条码支付请求:

    /// <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目录里找到

    这四个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));
        }
    }

      至此,支付宝条码支付功能就已经介绍完了,其他支付宝支付的调用也是类似的。觉得不错请点赞支持我喔,下篇将介绍微信扫码支付的示例。

  • 相关阅读:
    【转】【金蝶K3Cloud】 分页账表
    【转】【金蝶K3Cloud】 树形账表
    【金蝶K3Cloud】Python拼接字段
    性能分析及调优
    性能测试指南
    性能测试--测试指标
    性能测试--术语解释
    BurpSuite 安装使用
    BeEF 安装使用
    win10与vmware 中的kali linux 共享文件夹
  • 原文地址:https://www.cnblogs.com/hambert/p/4707729.html
Copyright © 2011-2022 走看看