WeChatPay implementation of the EasyAbp.PaymentService module.
We have launched an online demo for this module: https://pay.samples.easyabp.io
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:
public override void OnApplicationInitialization(ApplicationInitializationContext context) { var resolver = context.ServiceProvider.GetRequiredService<IPaymentServiceResolver>(); resolver.TryRegisterProvider(WeChatPayPaymentServiceProvider.PaymentMethod, typeof(WeChatPayPaymentServiceProvider)); }
-
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.
-
Users can use the API
/api/paymentService/payment/{id}/pay
to finish the payment, please put the necessary params in theExtraProperties
:{ "extraProperties": { "trade_type": "JSAPI", "appid": "wx81a2956875268fk8" // You can specify an appid or get it from the input from the client. } }
Skip the following steps if you are using the EasyAbp.EShop.
See more steps
-
Create a payment with the payment method
WeChatPay
.Other modules or apps that depend on PaymentService module should create payments via distributed events.
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
-
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.