Commit 47b4fc68 authored by gdlcf88's avatar gdlcf88

Close #28: Completed WeChatPay payment service provider.

parent 0fba7074
......@@ -10,7 +10,7 @@ namespace EasyAbp.EShop.Payments.WeChatPay
typeof(EShopPaymentsWeChatPayApplicationContractsModule),
typeof(AbpDddApplicationModule),
typeof(AbpAutoMapperModule)
)]
)]
public class EShopPaymentsWeChatPayApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
......
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Users;
namespace EasyAbp.EShop.Payments.WeChatPay
{
[Dependency(ServiceLifetime.Singleton, TryRegister = true)]
public class ClaimPaymentOpenIdProvider : IPaymentOpenIdProvider
{
public const string OpenIdClaimType = "WeChatOpenId";
private readonly ICurrentUser _currentUser;
public ClaimPaymentOpenIdProvider(ICurrentUser currentUser)
{
_currentUser = currentUser;
}
public Task<string> FindUserOpenIdAsync(Guid userId)
{
return Task.FromResult(userId == _currentUser.Id
? _currentUser.FindClaim(OpenIdClaimType).Value
: throw new NotSupportedException());
}
}
}
\ No newline at end of file
using Volo.Abp.Modularity;
using System.Collections.Generic;
using EasyAbp.Abp.WeChat.Pay;
using EasyAbp.Abp.WeChat.Pay.Infrastructure.OptionResolve;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
namespace EasyAbp.EShop.Payments.WeChatPay
{
[DependsOn(
typeof(EShopPaymentsWeChatPayDomainSharedModule)
)]
typeof(EShopPaymentsWeChatPayDomainSharedModule),
typeof(AbpWeChatPayModule)
)]
public class EShopPaymentsWeChatPayDomainModule : AbpModule
{
public override void PostConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<AbpWeChatPayResolveOptions>(options =>
{
options.ResolveContributors.AddFirst(new SettingOptionResolveContributor());
});
}
}
}
using System;
using System.Threading.Tasks;
using System.Xml;
using EasyAbp.Abp.WeChat.Pay.Infrastructure;
using EasyAbp.EShop.Payments.Payments;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Timing;
namespace EasyAbp.EShop.Payments.WeChatPay
{
public class EShopWeChatPayHandler : IWeChatPayHandler, ITransientDependency
{
private readonly IClock _clock;
private readonly IPaymentRepository _paymentRepository;
public EShopWeChatPayHandler(
IClock clock,
IPaymentRepository paymentRepository)
{
_clock = clock;
_paymentRepository = paymentRepository;
}
public virtual async Task HandleAsync(XmlDocument xmlDocument)
{
if (xmlDocument.Attributes == null || xmlDocument.Attributes["return_code"].Value != "SUCCESS")
{
return;
}
if (xmlDocument.Attributes["result_code"].Value == "SUCCESS")
{
var orderId = Guid.Parse(xmlDocument.Attributes["out_trade_no"].Value);
var payment = await _paymentRepository.GetAsync(orderId);
payment.SetExternalTradingCode(xmlDocument.Attributes["transaction_id"].Value);
payment.CompletePayment(_clock.Now);
await _paymentRepository.UpdateAsync(payment, true);
}
// Todo: record xml
}
}
}
\ No newline at end of file
......@@ -8,6 +8,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="EasyAbp.Abp.WeChat.Pay" Version="1.0.3" />
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="2.7.0" />
<ProjectReference Include="..\..\..\EasyAbp.EShop.Payments\src\EasyAbp.EShop.Payments.Domain\EasyAbp.EShop.Payments.Domain.csproj" />
<ProjectReference Include="..\EasyAbp.EShop.Payments.WeChatPay.Domain.Shared\EasyAbp.EShop.Payments.WeChatPay.Domain.Shared.csproj" />
......
using System;
using System.Threading.Tasks;
namespace EasyAbp.EShop.Payments.WeChatPay
{
public interface IPaymentOpenIdProvider
{
Task<string> FindUserOpenIdAsync(Guid userId);
}
}
\ No newline at end of file
using System;
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Pay;
using EasyAbp.Abp.WeChat.Pay.Infrastructure.OptionResolve;
using EasyAbp.EShop.Payments.WeChatPay.Settings;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Settings;
namespace EasyAbp.EShop.Payments.WeChatPay
{
public class SettingOptionResolveContributor : IWeChatPayOptionResolveContributor
{
public const string ContributorName = "Setting";
public string Name => ContributorName;
public virtual async Task ResolveAsync(WeChatPayOptionsResolverContext context)
{
var settingProvider = context.ServiceProvider.GetRequiredService<ISettingProvider>();
context.Options = new AbpWeChatPayOptions
{
ApiKey = await settingProvider.GetOrNullAsync(WeChatPaySettings.WeChatPayPaymentMethod.ApiKey),
MchId = await settingProvider.GetOrNullAsync(WeChatPaySettings.WeChatPayPaymentMethod.MchId),
IsSandBox = Convert.ToBoolean(await settingProvider.GetOrNullAsync(WeChatPaySettings.WeChatPayPaymentMethod.IsSandBox)),
NotifyUrl = await settingProvider.GetOrNullAsync(WeChatPaySettings.WeChatPayPaymentMethod.NotifyUrl),
RefundNotifyUrl = await settingProvider.GetOrNullAsync(WeChatPaySettings.WeChatPayPaymentMethod.RefundNotifyUrl),
CertificatePath = await settingProvider.GetOrNullAsync(WeChatPaySettings.WeChatPayPaymentMethod.CertificatePath),
CertificateSecret = await settingProvider.GetOrNullAsync(WeChatPaySettings.WeChatPayPaymentMethod.CertificateSecret)
};
}
}
}
\ No newline at end of file
using Volo.Abp.Settings;
using System;
using Microsoft.Extensions.Configuration;
using Volo.Abp.Settings;
namespace EasyAbp.EShop.Payments.WeChatPay.Settings
{
public class WeChatPaySettingDefinitionProvider : SettingDefinitionProvider
{
private readonly IConfiguration _configuration;
public WeChatPaySettingDefinitionProvider(IConfiguration configuration)
{
_configuration = configuration;
}
public override void Define(ISettingDefinitionContext context)
{
/* Define module settings here.
* Use names from WeChatPaySettings class.
*/
context.Add(
new SettingDefinition(WeChatPaySettings.WeChatPayPaymentMethod.MchId),
new SettingDefinition(WeChatPaySettings.WeChatPayPaymentMethod.ApiKey),
new SettingDefinition(WeChatPaySettings.WeChatPayPaymentMethod.IsSandBox, "false"),
new SettingDefinition(WeChatPaySettings.WeChatPayPaymentMethod.NotifyUrl,
_configuration["App:SelfUrl"].EnsureEndsWith('/') + "WeChatPay/Notify"),
new SettingDefinition(WeChatPaySettings.WeChatPayPaymentMethod.RefundNotifyUrl,
_configuration["App:SelfUrl"].EnsureEndsWith('/') + "WeChatPay/RefundNotify"),
new SettingDefinition(WeChatPaySettings.WeChatPayPaymentMethod.CertificatePath),
new SettingDefinition(WeChatPaySettings.WeChatPayPaymentMethod.CertificateSecret)
);
}
}
}
\ No newline at end of file
......@@ -7,5 +7,18 @@
/* Add constants for setting names. Example:
* public const string MySettingName = GroupName + ".MySettingName";
*/
public static class WeChatPayPaymentMethod
{
private const string PaymentMethodName = GroupName + ".WeChatPay";
public const string MchId = PaymentMethodName + ".MchId";
public const string ApiKey = PaymentMethodName + ".ApiKey";
public const string IsSandBox = PaymentMethodName + ".IsSandBox";
public const string NotifyUrl = PaymentMethodName + ".NotifyUrl";
public const string RefundNotifyUrl = PaymentMethodName + ".RefundNotifyUrl";
public const string CertificatePath = PaymentMethodName + ".CertificatePath";
public const string CertificateSecret = PaymentMethodName + ".CertificateSecret";
}
}
}
\ No newline at end of file
using Volo.Abp;
namespace EasyAbp.EShop.Payments.WeChatPay
{
public class UnifiedOrderFailedException : BusinessException
{
public UnifiedOrderFailedException(string returnCode, string returnMsg) : base(
message: $"Unified order failed, return_code: {returnCode}, return_msg: {returnMsg}")
{
}
public UnifiedOrderFailedException(string returnCode, string returnMsg, string errCode, string errCodeDes) :
base(message: $"Unified order failed, return_code: {returnCode}, return_msg: {returnMsg}, err_code: {errCode}, err_code_des: {errCodeDes}")
{
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Pay.Services.Pay;
using EasyAbp.EShop.Payments.Payments;
using EasyAbp.EShop.Payments.WeChatPay.Settings;
using Microsoft.Extensions.Configuration;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Settings;
namespace EasyAbp.EShop.Payments.WeChatPay
{
public class WeChatPayPaymentServiceProvider : IPaymentServiceProvider, ITransientDependency
{
private readonly ServiceProviderPayService _serviceProviderPayService;
private readonly IConfiguration _configuration;
private readonly ISettingProvider _settingProvider;
private readonly IPaymentOpenIdProvider _paymentOpenIdProvider;
private readonly IPaymentRepository _paymentRepository;
public const string PaymentMethod = "WeChatPay";
public WeChatPayPaymentServiceProvider(
ServiceProviderPayService serviceProviderPayService,
IConfiguration configuration,
ISettingProvider settingProvider,
IPaymentOpenIdProvider paymentOpenIdProvider,
IPaymentRepository paymentRepository)
{
_serviceProviderPayService = serviceProviderPayService;
_configuration = configuration;
_settingProvider = settingProvider;
_paymentOpenIdProvider = paymentOpenIdProvider;
_paymentRepository = paymentRepository;
}
public async Task<Payment> PayAsync(Payment payment, Dictionary<string, object> inputExtraProperties,
Dictionary<string, object> payeeConfigurations)
{
if (payment.Currency != "CNY")
{
throw new CurrencyNotSupportedException(payment.PaymentMethod, payment.Currency);
}
var payeeAccount = payeeConfigurations.GetOrDefault("PayeeAccount") as string ??
await _settingProvider.GetOrNullAsync(WeChatPaySettings.WeChatPayPaymentMethod
.MchId);
payment.SetPayeeAccount(payeeAccount);
var openId = await _paymentOpenIdProvider.FindUserOpenIdAsync(payment.UserId);
var outTradeNo = payment.Id.ToString("N");
var result = await _serviceProviderPayService.UnifiedOrderAsync(
appId: inputExtraProperties.GetOrDefault("appid") as string,
subAppId: null,
mchId: payment.PayeeAccount,
subMchId: null,
deviceInfo: payeeConfigurations.GetOrDefault("deviceInfo") as string ?? "EasyAbp Payment Service",
body: payeeConfigurations.GetOrDefault("body") as string ?? "EasyAbp Payment Service",
detail: payeeConfigurations.GetOrDefault("detail") as string,
attach: payeeConfigurations.GetOrDefault("attach") as string,
outTradeNo: outTradeNo,
feeType: payment.Currency,
totalFee: ConvertDecimalToWeChatPayFee(payment.ActualPaymentAmount),
billCreateIp: "127.0.0.1",
timeStart: null,
timeExpire: null,
goodsTag: payeeConfigurations.GetOrDefault("goods_tag") as string,
notifyUrl: payeeConfigurations.GetOrDefault("notify_url") as string
?? _configuration["App:SelfUrl"].EnsureEndsWith('/') + "WeChatPay/Notify",
tradeType: inputExtraProperties.GetOrDefault("trade_type") as string,
productId: null,
limitPay: payeeConfigurations.GetOrDefault("limit_pay") as string,
openId: openId,
subOpenId: null,
receipt: payeeConfigurations.GetOrDefault("receipt") as string ?? "N",
sceneInfo: null);
if (result.Attributes == null || result.Attributes["return_code"].Value != "SUCCESS")
{
throw new UnifiedOrderFailedException(result.Attributes?["return_code"].Value, result.Attributes?["return_msg"].Value);
}
if (result.Attributes["result_code"].Value != "SUCCESS")
{
throw new UnifiedOrderFailedException(result.Attributes["return_code"]?.Value,
result.Attributes["return_msg"]?.Value, result.Attributes["err_code_des"]?.Value,
result.Attributes["err_code"]?.Value);
}
payment.SetProperty("trade_type", result.Attributes["trade_type"]);
payment.SetProperty("prepay_id", result.Attributes["prepay_id"]);
payment.SetProperty("code_url", result.Attributes["code_url"]);
return await _paymentRepository.UpdateAsync(payment, true);
}
private static int ConvertDecimalToWeChatPayFee(decimal paymentActualPaymentAmount)
{
return Convert.ToInt32(decimal.Round(paymentActualPaymentAmount, 2, MidpointRounding.AwayFromZero) * 100);
}
}
}
\ No newline at end of file
using Localization.Resources.AbpUi;
using EasyAbp.Abp.WeChat.Pay.HttpApi;
using Localization.Resources.AbpUi;
using EasyAbp.EShop.Payments.WeChatPay.Localization;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Localization;
......@@ -9,7 +10,9 @@ namespace EasyAbp.EShop.Payments.WeChatPay
{
[DependsOn(
typeof(EShopPaymentsWeChatPayApplicationContractsModule),
typeof(AbpAspNetCoreMvcModule))]
typeof(AbpAspNetCoreMvcModule),
typeof(AbpWeChatPayHttpApiModule)
)]
public class EShopPaymentsWeChatPayHttpApiModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
......
......@@ -8,6 +8,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="EasyAbp.Abp.WeChat.Pay.HttpApi" Version="1.0.3" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="2.7.0" />
<ProjectReference Include="..\EasyAbp.EShop.Payments.WeChatPay.Application.Contracts\EasyAbp.EShop.Payments.WeChatPay.Application.Contracts.csproj" />
</ItemGroup>
......
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyAbp.EShop.Orders.Orders;
using Volo.Abp.DependencyInjection;
......@@ -39,6 +40,20 @@ namespace EasyAbp.EShop.Payments.Payments
return false;
}
var inputStoreIdString = inputExtraProperties.GetOrDefault("StoreId") as string;
if (order.StoreId.ToString() != inputStoreIdString)
{
if (inputStoreIdString == null)
{
inputExtraProperties.Add("StoreId", order.StoreId);
}
else
{
return false;
}
}
return order.OrderStatus == OrderStatus.Pending;
}
}
......
......@@ -7,6 +7,7 @@ using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Users;
namespace EasyAbp.EShop.Payments.Payments
{
......@@ -31,15 +32,12 @@ namespace EasyAbp.EShop.Payments.Payments
{
await CheckCreatePolicyAsync();
var providerType = await _paymentServiceResolver.GetProviderTypeOrDefaultAsync(input.PaymentMethod);
var provider = ServiceProvider.GetService(providerType) as IPaymentServiceProvider;
var providerType = await _paymentServiceResolver.GetProviderTypeOrDefaultAsync(input.PaymentMethod) ??
throw new UnknownPaymentMethodException(input.PaymentMethod);
var provider = ServiceProvider.GetService(providerType) as IPaymentServiceProvider ??
throw new UnknownPaymentMethodException(input.PaymentMethod);
if (providerType == null || provider == null)
{
throw new UnknownPaymentMethodException(input.PaymentMethod);
}
var paymentItems = input.PaymentItems.Select(inputPaymentItem =>
new PaymentItem(GuidGenerator.Create(), inputPaymentItem.ItemType, inputPaymentItem.ItemKey,
inputPaymentItem.Currency, inputPaymentItem.OriginalPaymentAmount)).ToList();
......@@ -49,32 +47,38 @@ namespace EasyAbp.EShop.Payments.Payments
throw new MultiCurrencyNotSupportedException();
}
var payment = new Payment(GuidGenerator.Create(), CurrentTenant.Id, input.PaymentMethod, input.Currency,
paymentItems.Select(item => item.OriginalPaymentAmount).Sum(), paymentItems);
var payment = new Payment(GuidGenerator.Create(), CurrentTenant.Id, CurrentUser.GetId(),
input.PaymentMethod, input.Currency, paymentItems.Select(item => item.OriginalPaymentAmount).Sum(),
paymentItems);
await Repository.InsertAsync(payment, autoSave: true);
await CheckPayableAsync(payment, input.ExtraProperties);
await FillPayeeAccountAsync(payment, input.ExtraProperties);
var payeeConfigurations = await GetPayeeConfigurationsAsync(payment, input.ExtraProperties);
// Todo: payment discount
await provider.PayAsync(payment);
await provider.PayAsync(payment, input.ExtraProperties, payeeConfigurations);
return MapToGetOutputDto(payment);
}
protected virtual async Task FillPayeeAccountAsync(Payment payment, Dictionary<string, object> inputExtraProperties)
protected virtual Task<Dictionary<string, object>> GetPayeeConfigurationsAsync(Payment payment,
Dictionary<string, object> inputExtraProperties)
{
payment.SetPayeeAccount(
await _paymentPayeeAccountProvider.GetPayeeAccountAsync(payment, inputExtraProperties));
// Todo: use payee configurations provider.
// Todo: get store side payee configurations.
var payeeConfigurations = new Dictionary<string, object>();
return Task.FromResult(payeeConfigurations);
}
protected virtual async Task CheckPayableAsync(Payment payment, Dictionary<string, object> inputExtraProperties)
{
var itemSet = new HashSet<PaymentItem>(payment.PaymentItems);
foreach (var authorizer in ServiceProvider.GetServices<IPaymentAuthorizer>())
{
foreach (var item in itemSet.ToList())
......
using EasyAbp.EShop.Payments.Payments;
using EasyAbp.EShop.Stores;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp;
using Volo.Abp.AutoMapper;
using Volo.Abp.EventBus.Distributed;
......@@ -15,6 +16,11 @@ namespace EasyAbp.EShop.Payments
)]
public class EShopPaymentsDomainModule : AbpModule
{
public override void PostConfigureServices(ServiceConfigurationContext context)
{
context.Services.TryAddTransient<IPaymentServiceProvider, FreePaymentServiceProvider>();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var resolver = context.ServiceProvider.GetService<IPaymentServiceResolver>();
......
using System;
using Volo.Abp;
namespace EasyAbp.EShop.Payments.Payments
{
public class CurrencyNotSupportedException : BusinessException
{
public CurrencyNotSupportedException(string paymentMethod, string currency) : base(
message: $"Payment method {paymentMethod} does not support currency: {currency}")
{
}
public CurrencyNotSupportedException(string paymentMethod, string currency, Guid storeId) : base(
message: $"Payment method {paymentMethod} in store {storeId} does not support currency: {currency}")
{
}
}
}
\ No newline at end of file
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
......@@ -6,7 +7,8 @@ using Volo.Abp.Timing;
namespace EasyAbp.EShop.Payments.Payments
{
[Dependency(ServiceLifetime.Transient, TryRegister = true)]
// [ExposeServices(typeof(IPaymentRepository))]
// [Dependency(ServiceLifetime.Transient, TryRegister = true)]
public class FreePaymentServiceProvider : IPaymentServiceProvider
{
private readonly IClock _clock;
......@@ -20,13 +22,16 @@ namespace EasyAbp.EShop.Payments.Payments
_clock = clock;
_paymentRepository = paymentRepository;
}
public async Task<Payment> PayAsync(Payment payment, Dictionary<string, object> extraProperties = null)
public async Task<Payment> PayAsync(Payment payment, Dictionary<string, object> inputExtraProperties,
Dictionary<string, object> payeeConfigurations)
{
payment.SetExternalTradingCode(payment.Id.ToString());
payment.SetPayeeAccount("None");
payment.SetExternalTradingCode(payment.Id.ToString());
payment.CompletePayment(_clock.Now);
return await _paymentRepository.UpdateAsync(payment, true);
}
}
......
......@@ -6,6 +6,7 @@ namespace EasyAbp.EShop.Payments.Payments
{
public interface IPaymentServiceProvider
{
Task<Payment> PayAsync(Payment payment, Dictionary<string, object> extraProperties = null);
Task<Payment> PayAsync(Payment payment, Dictionary<string, object> inputExtraProperties,
Dictionary<string, object> payeeConfigurations);
}
}
\ No newline at end of file
using Volo.Abp;
namespace EasyAbp.EShop.Payments.Payments
{
public class PayeeConfigurationMissingValueException : BusinessException
{
public PayeeConfigurationMissingValueException(string paymentMethod, string configurationKey) : base(
message: $"Payment method ({paymentMethod}) is missing configuration: {configurationKey}.")
{
}
}
}
\ No newline at end of file
......@@ -10,6 +10,8 @@ namespace EasyAbp.EShop.Payments.Payments
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid UserId { get; protected set; }
[NotNull]
public virtual string PaymentMethod { get; protected set; }
......@@ -42,6 +44,7 @@ namespace EasyAbp.EShop.Payments.Payments
public Payment(
Guid id,
Guid? tenantId,
Guid userId,
[NotNull] string paymentMethod,
[NotNull] string currency,
decimal originalPaymentAmount,
......@@ -49,10 +52,13 @@ namespace EasyAbp.EShop.Payments.Payments
) :base(id)
{
TenantId = tenantId;
UserId = userId;
PaymentMethod = paymentMethod;
Currency = currency;
OriginalPaymentAmount = originalPaymentAmount;
ActualPaymentAmount = originalPaymentAmount;
PaymentItems = paymentItems;
RefundAmount = 0;
}
public void SetPayeeAccount([NotNull] string payeeAccount)
......@@ -67,16 +73,12 @@ namespace EasyAbp.EShop.Payments.Payments
ExternalTradingCode = externalTradingCode;
}
public void SetPaymentDiscount(
decimal paymentDiscount,
decimal actualPaymentAmount,
decimal refundAmount)
public void SetPaymentDiscount(decimal paymentDiscount)
{
CheckPaymentIsNotCompleted();
PaymentDiscount = paymentDiscount;
ActualPaymentAmount = actualPaymentAmount;
RefundAmount = refundAmount;
ActualPaymentAmount -= paymentDiscount;
}
public void CompletePayment(DateTime completionTime)
......
......@@ -6,7 +6,7 @@ namespace EasyAbp.EShop.Payments.Payments
public class PaymentHasAlreadyBeenCompletedException : BusinessException
{
public PaymentHasAlreadyBeenCompletedException(Guid id) : base(
message: $"Payment({id}) has already been completed.")
message: $"Payment ({id}) has already been completed.")
{
}
}
......
using EasyAbp.EShop.Baskets;
using EasyAbp.EShop.Orders;
using EasyAbp.EShop.Payments;
using EasyAbp.EShop.Payments.Payments;
using EasyAbp.EShop.Payments.WeChatPay;
using EasyAbp.EShop.Products;
using EasyAbp.EShop.Stores;
using EasyMall.MultiTenancy;
using EasyMall.ObjectExtending;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.AuditLogging;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.FeatureManagement;
......@@ -52,5 +55,12 @@ namespace EasyMall
options.IsEnabled = MultiTenancyConsts.IsEnabled;
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var resolver = context.ServiceProvider.GetService<IPaymentServiceResolver>();
resolver.TryRegisterProviderAsync(WeChatPayPaymentServiceProvider.PaymentMethod, typeof(WeChatPayPaymentServiceProvider));
}
}
}
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace EasyMall.Migrations
{
public partial class AddedUserIdToPayment : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "UserId",
table: "PaymentsPayments",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "UserId",
table: "PaymentsPayments");
}
}
}
......@@ -279,6 +279,9 @@ namespace EasyMall.Migrations
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.ToTable("PaymentsPayments");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment