Prepayment 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.Prepayment.Application
- EasyAbp.PaymentService.Prepayment.Application.Contracts
- EasyAbp.PaymentService.Prepayment.Domain
- EasyAbp.PaymentService.Prepayment.Domain.Shared
- EasyAbp.PaymentService.Prepayment.EntityFrameworkCore
- EasyAbp.PaymentService.Prepayment.HttpApi
- EasyAbp.PaymentService.Prepayment.HttpApi.Client
- (Optional) EasyAbp.PaymentService.Prepayment.MongoDB
- (Optional) EasyAbp.PaymentService.Prepayment.Web
-
Add
DependsOn(typeof(PaymentServicePrepaymentXxxModule))
attribute to configure the module dependencies. (see how) -
Add
builder.ConfigurePaymentServicePrepayment();
to theOnModelCreating()
method in MyProjectMigrationsDbContext.cs. -
Add EF Core migrations and update your database. See: ABP document.
-
Register the Prepayment payment method:
Configure<PaymentServiceOptions>(options => { options.Providers.Configure<PrepaymentPaymentServiceProvider>(PrepaymentPaymentServiceProvider.PaymentMethod); });
-
Configure the prepayment to define a account group:
Configure<PaymentServicePrepaymentOptions>(options => { options.AccountGroups.Configure<DefaultAccountGroup>(accountGroup => { accountGroup.Currency = "CNY"; }); });
please refer to the
ConfigurePaymentServicePrepayment
method in the Web module of the sample app. -
Use the API
/api/payment-service/prepayment/account
(with the request paramUserId
), then the account will be created automatically. -
Top up your account:
-
Use the API
/api/payment-service/prepayment/account/top-up
to start top-up. -
Use the API
/api/payment-service/prepayment/account/{id}
to get theExtraProperties.PendingTopUpPaymentId
. -
Use the API
/api/payment-service/payment/{id}/pay
to finish the payment. (for example you can use WeChatPay to top up your prepayment account, please refer to the document of the payment method you want) -
If you want to cancel an ongoing payment, please use the API
/api/payment-service/payment/{id}/cancel
.
Or just change the balance directly with the management pages if you have the account management permission.
-
-
Pay with prepayment account.
-
Create a payment with the payment method
Prepayment
.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 = "Prepayment", // Should specify the payment method as "Prepayment" Currency = "CNY", // Should be same as the currency configuration of your prepayment account group 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
-
Use the API
/api/payment-service/payment/{id}/pay
to finish the payment, please put the necessary params in theExtraProperties
:{ "extraProperties": { "AccountId": "82D49C17-9282-4822-9EE9-A0685529D707" // Id of the prepayment account that you use to pay } }
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.