项目

创建自定义支付网关

使用此模块需要具备 ABP Team 或更高级的许可证

本文档将说明如何创建自定义支付网关,该网关与现有 支付模块中的支付网关有所不同。

创建核心功能

  • 在项目的 Domain 层创建 MyPaymentGateway.cs 并实现 IPaymentGateway 接口。

    public class MyPaymentGateway : IPaymentGateway, ITransientDependency
      {
          private readonly IPaymentRequestRepository paymentRequestRepository;
    
          public MyPaymentGateway(IPaymentRequestRepository paymentRequestRepository)
          {
              this.paymentRequestRepository = paymentRequestRepository;
          }
    
          public async Task<PaymentRequestStartResult> StartAsync(PaymentRequest paymentRequest, PaymentRequestStartInput input)
          {
              var totalPrice = paymentRequest.Products.Sum(x => x.TotalPrice);
    
              var checkoutLink = // 此处执行相关操作
    
              return new PaymentRequestStartResult
              {
                  CheckoutLink = checkoutLink + "returnUrl=" + input.ReturnUrl
              };
          }
    
          public async Task<PaymentRequest> CompleteAsync(Dictionary<string, string> parameters)
          {
              var token = parameters["token"]; // 可以获取支付网关提供的任意参数。例如:token、id、hash等。
    
              var result = ;// provider.Validate(token); 在此处验证支付
    
              var paymentRequest = await paymentRequestRepository.FindAsync(result.Id);
    
              paymentRequest.SetState(PaymentRequestState.Completed); // 根据结果将状态设为 completed 或其他。
    
              return paymentRequest;
          }
    
          public Task HandleWebhookAsync(string payload, Dictionary<string, string> headers)
          {
              // 如果没有配置 webhook,可以不实现此方法。
              throw new System.NotImplementedException();
          }
    
          public bool IsValid(PaymentRequest paymentRequest, Dictionary<string, string> properties)
          {
              // 在此处检查自定义逻辑,以确定该网关是否可用。
              return true;
          }
      }
    
  • 还需要在项目的 Domain 层配置 PaymentOptions,示例如下:

    Configure<PaymentOptions>(options =>
      {
          options.Gateways.Add(new PaymentGatewayConfiguration(
              "MyGateway",
              LocalizableString.Create<PaymentResource>("MyGateway"),
              isSubscriptionSupported: false,
              typeof(MyPaymentGateway)
              ));
      });
    

创建用户界面

系统默认支持两种页面类型。您可以定义支付前页面和支付后页面。

  • 创建 PreCheckout.cshtmlPreCheckout.cshtml.cs

    @model PreCheckoutModel
    
    <h3>支付前确认</h3>
    <form method="post">
        <button class="btn btn-success" asp-page-handler="ContinueToCheckout">
            继续前往收银台
            <i class="fa fa-long-arrow-right"></i>
        </button>
    </form>
    
    public class PreCheckoutModel : AbpPageModel
    {
        [BindProperty] public Guid PaymentRequestId { get; set; }
    
        public virtual ActionResult OnGet()
        {
            // 此处不支持 GET 操作。所有选择的网关请求都将以 POST 方式发送。
            return BadRequest();
        }
    
        public virtual async Task OnPostAsync()
        {
            // 可以通过 `PaymentRequestId` 从数据库获取支付请求,并在用户界面渲染相关内容。
        }
    
        public virtual async Task<IActionResult> OnPostContinueToCheckout()
        {
            return Redirect("网关的实际收银台链接");
        }
    }
    
  • 创建 PostCheckout.cshtmlPostCheckout.cshtml.cs

    @model PostCheckoutModel
    
    <h3>操作完成</h3>
    
  • 在项目的 Web 层使用 PaymentWebOptions 配置页面。

    Configure<PaymentWebOptions>(options =>
    {
        options.Gateways.Add(new PaymentGatewayWebConfiguration(
            name: "MyGateway",
            prePaymentUrl: "/MyGateway/PreCheckout", // 此页面将在支付前打开。
            isSubscriptionSupported: false,
            postPaymentUrl: "/MyGateway/PostCheckout" // 此页面将在支付后打开。
            ));
    });
    

您的自定义网关将出现在公共支付网关选择页面中。如果只有一个支付网关,则会跳过该页面。 ABP 支付自定义网关

在本文档中