WeChatPay implementation of the EasyAbp.PaymentService module.
Should also install the PaymentService module since this module depends on it.
-
Install the following NuGet packages. (see how)
- EasyAbp.PaymentService.WeChatPay.Application
- EasyAbp.PaymentService.WeChatPay.Application.Contracts
- EasyAbp.PaymentService.WeChatPay.Domain
- EasyAbp.PaymentService.WeChatPay.Domain.Shared
- EasyAbp.PaymentService.WeChatPay.EntityFrameworkCore
- EasyAbp.PaymentService.WeChatPay.HttpApi
- EasyAbp.PaymentService.WeChatPay.HttpApi.Client
- (Optional) EasyAbp.PaymentService.WeChatPay.MongoDB
- (Optional) EasyAbp.PaymentService.WeChatPay.Web
-
Add
DependsOn(typeof(PaymentServiceWeChatPayXxxModule))
attribute to configure the module dependencies. (see how) -
Add
builder.ConfigurePaymentServiceWeChatPay();
to theOnModelCreating()
method in MyProjectMigrationsDbContext.cs. -
Add EF Core migrations and update your database. See: ABP document.
-
Register the WeChatPay payment method:
Configure<PaymentServiceOptions>(options => { options.Providers.Configure<WeChatPayPaymentServiceProvider>(WeChatPayPaymentServiceProvider.PaymentMethod); });
-
Configure the WeChatPay settings, you can try to use SettingUI to finish this work.
See the demo, it is also according to the document of the EasyAbp.Abp.WeChat module.
-
Pay with WeChatPay.
-
Create a payment with the payment method
WeChatPay
.Other modules or apps should create payments via distributed events. Skip this step if you are using the EasyAbp.EShop.
See sample code
await _distributedEventBus.PublishAsync(new CreatePaymentEto { TenantId = CurrentTenant.Id, UserId = CurrentUser.GetId(), PaymentMethod = "WeChatPay", // Should specify the payment method as "WeChatPay" Currency = "CNY", // Should always be "CNY" PaymentItems = orders.Select(order => new CreatePaymentItemEto { ItemType = "MyCustomKeyword", // It is just a sample and you can customize it yourself ItemKey = order.Id, OriginalPaymentAmount = order.Price }).ToList() });
please refer to the usage in EShop
-
Users can use the API
/api/payment-service/payment/{id}/pay
(POST) to finish the payment, please put the necessary params in theExtraProperties
:{ "extraProperties": { "trade_type": "JSAPI", "appid": "wx81a2956875268fk8" "mch_id": "10000100" // If it's null, use the default settings/options value you configured in the Abp.WeChat.Pay module. } }
Then you can get a
prepay_id
orcode_url
from the extraProperty in the result. Refer to the WeChatPay V3 docs to continue the payment. This module can receive and allow you to handle the payment success event.
Skip the following steps if you are using the EasyAbp.EShop.
See more steps
-
Handle the payment created distributed event to get and remember the
PaymentId
.See sample code
public class MyCustomPaymentCreatedEventHandler : IDistributedEventHandler<EntityCreatedEto<PaymentEto>>, ITransientDependency { [UnitOfWork(isTransactional: true)] public virtual async Task HandleEventAsync(EntityCreatedEto<PaymentEto> eventData) { foreach (var item in eventData.Entity.PaymentItems.Where(item => item.ItemType == "MyCustomKeyword")) { // Persistence the PaymentId of the ongoing payment, so user can get it in some way. } } }
please refer to the usage in EShop
-
Handle the payment canceled distributed event to clear the remembered the
PaymentId
.See sample code
public class MyCustomPaymentCanceledEventHandler : IDistributedEventHandler<PaymentCanceledEto>, ITransientDependency { [UnitOfWork(isTransactional: true)] public virtual async Task HandleEventAsync(PaymentCanceledEto payment) { foreach (var item in payment.PaymentItems.Where(item => item.ItemType == "MyCustomKeyword")) { // Remove the remembered PaymentId. } } }
please refer to the usage in EShop
-
Handle the payment completed distributed event:
See sample code
public class MyCustomPaymentCompletedEventHandler : IDistributedEventHandler<PaymentCompletedEto>, ITransientDependency { [UnitOfWork(isTransactional: true)] public virtual async Task HandleEventAsync(PaymentCompletedEto payment) { foreach (var item in payment.PaymentItems.Where(item => item.ItemType == "MyCustomKeyword")) { // Maybe you can automatically send out the goods to the customer here. } } }
please refer to the usage in EShop
-
- Unit tests.