支付宝条码支付

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

  介绍完了条码支付后,给个文档接口吧:支付宝条码支付。条码支付整个流程主要需要的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));
    }
}

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

转载于:https://www.cnblogs.com/hambert/p/4707729.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值