Ezreal.SDK.ShouQianBa

Package Description


Keywords
preview
License
MIT
Install
Install-Package Ezreal.SDK.ShouQianBa -Version 0.1.1-preview

Documentation

Ezreal.ShouQianBaGitHub license

  • Ezreal.ShouQianBa.ApiClient是一个.NET实现的收钱吧WebApi连接库,旨在让您编写简单且可读性强代码快速接入收钱吧的WebApi
  • 同时支持 .NET Framework 4.5/.NET Standard 2.0+
  • 您可以直接通过nuget引用项目

NuGet 依赖项目

所有平台都必须的依赖项

仅.NET Standard需要的依赖项

版本状态:

Date Version Status
2019-01-10 0.1.0-preview release
2019-01-14 0.1.1-preview nuget only
2019-02-15 0.2.1-α release
2019-03-27 0.2.1-β cancel
2019-04-05 0.2.1 release
2019-05-15 0.3.0 release
2020-08-11 0.3.2 release

当前仓库代码版本 0.3.2

使用前

  • 如果您觉得项目对您有帮助,请务必star支持一下
  • 项目曾经名为Ezreal.SDK.ShouQianBa,因项目不符合SDK的定位更名为Ezreal.ShouQianBa.ApiClient
  • 作者不是收钱吧的开发者,因此有问题请Issues.
  • 项目是作者在接入收钱吧WebApi时创建的,.NET下没有相应的库,因此在此贡献出来给大家使用.
  • 代码使用MIT协议,您可以按照MIT协议处置代码
  • 若您在使用中发现收钱吧方面接口发生变动,请务必在百忙之中联系我。

使用-仅针对当前仓库

  • 配置
    ShouQianBaGlobal.InitializeDefaultConfig(config =>
    {
        //若您不是服务商而是从服务商获取了信息来调用支付相关接口,则无需进行此配置
        config.DefaultShouQianBaServiceProviderSettings = new ServiceProviderSettings()
        {
            ServiceProviderSerialNo = @vendor_sn,
            ServiceProviderKey = @vendor_key,
        };
        //不使用沙箱无需配置此项目
        //config.UseSandbox = true;
        //默认配置了收钱吧提供的生产环境Url,如果您的网络环境下请求不可直达该Url,请用代理地址覆盖此项,沙箱环境同理。
        //config.ProductionEnvironmentApiUri = "生产环境Url";
        //若您希望记录日志请开启此项并配置LoggerFactory
        //config.UseLog = true;
    }/*, new LoggerFactory().AddConsole()*/);

以下演示简单使用,依赖注入请参照Demo项目适当更改代码

  • 开始使用
   BankRequestModel requestModel = new BankRequestModel() { BankCard = bankCardNo };
   var apiInstense = Global.Create<IMerchantContract>();
   var sign = ServiceProviderSignProvider.CreateFromServiceProviderSettings().Sign(requestModel);          
   Response<BankResponseModel> result = await apiInstense.Banks(sign, requestModel);
  • 当面付示例
        public static async void PayDemo()
        {

             TerminalSignSettings terminalSignSettings = new TerminalSignSettings()
            {
                TerminalKey = "设备Key(通过设备激活接口获得,或者通过设备签到接口刷新)",
                TerminalSerialNo = "设备序列号(通过设备激活接口获得)"
            };

            //当面付示例
            OrderCreateRequestModel orderCreateRequestModel = new OrderCreateRequestModel();
            orderCreateRequestModel.TerminalSerialNo = terminalSignSettings.TerminalSerialNo;
            orderCreateRequestModel.DeviceID = "设备的唯一编码";
            orderCreateRequestModel.ClientSerialNo = "调用方的订单号";
            orderCreateRequestModel.Operator = "调用方业务关联的操作员";
            orderCreateRequestModel.PayCertificate = "支付凭证,条码支付场景下为条码内容";
            orderCreateRequestModel.Summary = $"扣款{0.01}元";
            orderCreateRequestModel.TotalAmount = 0.01m;
            Response<OrderGenericResponseModel> result = null;
            ShouQianBaOrder shouQianBaOrder = null;
            try
            {
                result = await _wosaipayClient.Pay(orderCreateRequestModel, terminalSignSettings, TimeSpan.FromSeconds(5))
                .Retry(3, TimeSpan.FromSeconds(5))
                .WhenCatch<HttpStatusFailureException>(ex => ex.StatusCode == System.Net.HttpStatusCode.RequestTimeout);
            }
            //与支付宝/微信等支付服务直接提供商相比,此接口的流程存在差异,收钱吧方面这个请求是同步且持续阻塞的
            //当用户未支付时会一直pending,并不会返回等待支付的状态,因此Pay接口的预定义超时时间是50ms
            //一般而言是等待可以直接得到最终的正确结果,但不建议使用此方式,示例仍设定5s超时时间,在其超时后通过轮询的方式轮询最终态来确定结果
            catch (HttpStatusFailureException ex)
            {
                _logger.LogError($"收钱吧服务商支付发起刷卡支付交易在指定时间内返回了Http协议的失败或错误 {ex}");
            }
            catch (HttpApiException ex)
            {
                if (ex.InnerException is TaskCanceledException)
                {
                    //此处消除 主动超时 异常使业务继续
                    _logger.LogInformation($"收钱吧服务商支付发起刷卡支付交易在指定时间没有返回结果,主动取消等待转入轮询");
                }

            }
            catch (Exception ex)
            {
                _logger.LogError($"收钱吧服务商支付发起刷卡支付交易发生了错误 {ex}");
            }
            if (result != null
                && result.ExistsBusinessResponseContent
                && result.BusinessResponseContent.IsEffectiveOrder
                && result.BusinessResponseContent.Order.OrderStatus == OrderStatusEnum.PAID)
            {
                _logger.LogInformation("收钱吧支付成功");
                shouQianBaOrder = result.BusinessResponseContent.Order;
                //直接认为支付成功
            }
            else
            {
                OrderTokenRequestModel orderTokenRequestModel = new OrderTokenRequestModel()
                {
                    TerminalSerialNo = orderCreateRequestModel.TerminalSerialNo,
                    ClientSerialNo = orderCreateRequestModel.ClientSerialNo,
                    //由于Pay接口调用时无法确定拿到结果,因此收钱吧方面的订单号是不确定的,因此不建议使用此值。
                    SerialNo = null
                };
                using (CancellationTokenSource queryTaskCancelTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(120)))
                {
                    try
                    {
                        result = await _wosaipayClient.Query(orderTokenRequestModel, terminalSignSettings, TimeSpan.FromSeconds(5), queryTaskCancelTokenSource.Token)
                        .Retry(60, TimeSpan.FromSeconds(2))//设定轮询等待为2s,轮询不超过30次
                        .WhenCatch<HttpStatusFailureException>(ex => ex.StatusCode == System.Net.HttpStatusCode.RequestTimeout)
                        .WhenResult(response =>
                        {
                            if (!response.ExistsBusinessResponseContent)
                            {
                                return false;//请求异常中止重试
                            }
                            if (!response.BusinessResponseContent.IsEffectiveOrder)
                            {
                                return false;//业务异常中止重试
                            }

                            if (!response.BusinessResponseContent.Order.IsFinalOrderStatus)
                            {
                                return true;
                            }
                            return false;//订单到达最终态中止重试
                        }
                        );
                    }
                    catch (HttpStatusFailureException ex)
                    {
                        _logger.LogError($"收钱吧服务商刷卡支付查询在指定时间内返回了Http协议的失败或错误 {ex}");
                    }
                    catch (HttpApiException ex)
                    {
                        if (ex.InnerException is TaskCanceledException)
                        {
                            //此处消除 主动超时 异常使业务继续
                            _logger.LogInformation($"收钱吧服务商刷卡支付查询在指定时间没有返回结果,主动取消等待转入轮询");
                        }

                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"收钱吧服务商刷卡支付查询发生了错误 {ex}");
                    }
                    finally
                    {
                        queryTaskCancelTokenSource.Cancel();
                    }
                }


                if (result != null
                    && result.ExistsBusinessResponseContent
                    && result.BusinessResponseContent.IsEffectiveOrder
                    && result.BusinessResponseContent.Order.IsFinalOrderStatus)
                {
                    shouQianBaOrder = result.BusinessResponseContent.Order;
                    if (result.BusinessResponseContent.Order.OrderStatus == OrderStatusEnum.PAID)
                    {
                        _logger.LogInformation("收钱吧轮询到成功");
                        //直接认为支付成功

                    }
                    else
                    {
                        //符合此条件认为轮询到支付失败
                        _logger.LogError("收钱吧订单轮询到失败{0}@{1}-{2}", result.BusinessResponseContent.ResultCode, result.BusinessResponseContent.ErrorCode, result.BusinessResponseContent.ErrorMessage);
                    }

                }
                else
                {
                    //类似查询任务,轮询查询无法得到最终态结果时,需要调用撤单接口

                    using (CancellationTokenSource cancelTaskCancelTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(50)))
                    {

                        try
                        {
                            result = await _wosaipayClient.Cancel(orderTokenRequestModel, terminalSignSettings, TimeSpan.FromSeconds(5), cancelTaskCancelTokenSource.Token)
                            .Retry(30, TimeSpan.FromSeconds(2))//设定轮询等待为2s,轮询不超过30次
                            .WhenCatch<HttpStatusFailureException>(ex => ex.StatusCode == System.Net.HttpStatusCode.RequestTimeout)
                            .WhenResult(response =>
                            {
                                if (!response.ExistsBusinessResponseContent)
                                {
                                    return false;//请求异常中止重试
                                }
                                if (!response.BusinessResponseContent.IsEffectiveOrder)
                                {
                                    return false;//业务异常中止重试
                                }

                                if (!response.BusinessResponseContent.Order.IsFinalOrderStatus)
                                {
                                    //未达最终态继续重试

                                    return true;
                                }
                                return false;//订单到达最终态中止重试
                            }
                            );
                        }

                        catch (HttpStatusFailureException ex)
                        {
                            _logger.LogError($"收钱吧服务商刷卡支付撤单在指定时间内返回了Http协议的失败或错误 {ex}");
                        }
                        catch (HttpApiException ex)
                        {
                            if (ex.InnerException is TaskCanceledException)
                            {
                                //此处消除 主动超时 异常使业务继续
                                _logger.LogInformation($"收钱吧服务商刷卡支付撤单在指定时间没有返回结果,主动取消等待转入轮询");
                            }

                        }
                        catch (Exception ex)
                        {
                            _logger.LogError($"收钱吧服务商支付刷卡支付撤单发生了错误 {ex}");
                        }
                        finally
                        {
                            cancelTaskCancelTokenSource.Cancel();
                        }
                    }
                    //判断撤单结果
                    if (result != null
                    && result.ExistsBusinessResponseContent
                    && result.BusinessResponseContent.IsEffectiveOrder)
                    {
                        _logger.LogInformation("轮询到{0}", result.BusinessResponseContent.Order.OrderStatus);

                    }
                    else
                    {
                        _logger.LogInformation("未轮询到有效内容");
                    }
                }
            }
  • 更多使用方式尽情期待

捐赠

如果觉得这个项目不错,请支持Ezreal。Ezreal希望你也参与到.NET开源生态建设中来

联系

QQ:997229225