Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
E
EShop
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tsai
EShop
Commits
47b4fc68
Commit
47b4fc68
authored
May 09, 2020
by
gdlcf88
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Close #28: Completed WeChatPay payment service provider.
parent
0fba7074
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
3331 additions
and
39 deletions
+3331
-39
EShopPaymentsWeChatPayApplicationModule.cs
...ay.Application/EShopPaymentsWeChatPayApplicationModule.cs
+1
-1
ClaimPaymentOpenIdProvider.cs
...p.Payments.WeChatPay.Domain/ClaimPaymentOpenIdProvider.cs
+28
-0
EShopPaymentsWeChatPayDomainModule.cs
...ts.WeChatPay.Domain/EShopPaymentsWeChatPayDomainModule.cs
+16
-3
EShopWeChatPayHandler.cs
....EShop.Payments.WeChatPay.Domain/EShopWeChatPayHandler.cs
+47
-0
EasyAbp.EShop.Payments.WeChatPay.Domain.csproj
...Pay.Domain/EasyAbp.EShop.Payments.WeChatPay.Domain.csproj
+1
-0
IPaymentOpenIdProvider.cs
...EShop.Payments.WeChatPay.Domain/IPaymentOpenIdProvider.cs
+10
-0
SettingOptionResolveContributor.cs
...ments.WeChatPay.Domain/SettingOptionResolveContributor.cs
+32
-0
WeChatPaySettingDefinitionProvider.cs
...Pay.Domain/Settings/WeChatPaySettingDefinitionProvider.cs
+22
-1
WeChatPaySettings.cs
...p.Payments.WeChatPay.Domain/Settings/WeChatPaySettings.cs
+13
-0
UnifiedOrderFailedException.cs
....Payments.WeChatPay.Domain/UnifiedOrderFailedException.cs
+17
-0
WeChatPayPaymentServiceProvider.cs
...ments.WeChatPay.Domain/WeChatPayPaymentServiceProvider.cs
+106
-0
EShopPaymentsWeChatPayHttpApiModule.cs
....WeChatPay.HttpApi/EShopPaymentsWeChatPayHttpApiModule.cs
+5
-2
EasyAbp.EShop.Payments.WeChatPay.HttpApi.csproj
...y.HttpApi/EasyAbp.EShop.Payments.WeChatPay.HttpApi.csproj
+1
-0
EShopOrderPaymentAuthorizer.cs
...bp/EShop/Payments/Payments/EShopOrderPaymentAuthorizer.cs
+16
-1
PaymentAppService.cs
...tion/EasyAbp/EShop/Payments/Payments/PaymentAppService.cs
+21
-17
EShopPaymentsDomainModule.cs
...omain/EasyAbp/EShop/Payments/EShopPaymentsDomainModule.cs
+6
-0
CurrencyNotSupportedException.cs
.../EShop/Payments/Payments/CurrencyNotSupportedException.cs
+18
-0
FreePaymentServiceProvider.cs
...Abp/EShop/Payments/Payments/FreePaymentServiceProvider.cs
+11
-6
IPaymentServiceProvider.cs
...asyAbp/EShop/Payments/Payments/IPaymentServiceProvider.cs
+2
-1
PayeeConfigurationMissingValueException.cs
...ments/Payments/PayeeConfigurationMissingValueException.cs
+12
-0
Payment.cs
...ayments.Domain/EasyAbp/EShop/Payments/Payments/Payment.cs
+8
-6
PaymentHasAlreadyBeenCompletedException.cs
...ments/Payments/PaymentHasAlreadyBeenCompletedException.cs
+1
-1
EasyMallDomainModule.cs
...l/aspnet-core/src/EasyMall.Domain/EasyMallDomainModule.cs
+10
-0
20200508090003_AddedUserIdToPayment.Designer.cs
...igrations/20200508090003_AddedUserIdToPayment.Designer.cs
+2900
-0
20200508090003_AddedUserIdToPayment.cs
...rations/Migrations/20200508090003_AddedUserIdToPayment.cs
+24
-0
EasyMallMigrationsDbContextModelSnapshot.cs
...ns/Migrations/EasyMallMigrationsDbContextModelSnapshot.cs
+3
-0
No files found.
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.Application/EShopPaymentsWeChatPayApplicationModule.cs
View file @
47b4fc68
...
...
@@ -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
)
...
...
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.Domain/ClaimPaymentOpenIdProvider.cs
0 → 100644
View file @
47b4fc68
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
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.Domain/EShopPaymentsWeChatPayDomainModule.cs
View file @
47b4fc68
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
());
});
}
}
}
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.Domain/EShopWeChatPayHandler.cs
0 → 100644
View file @
47b4fc68
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
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.Domain/EasyAbp.EShop.Payments.WeChatPay.Domain.csproj
View file @
47b4fc68
...
...
@@ -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" />
...
...
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.Domain/IPaymentOpenIdProvider.cs
0 → 100644
View file @
47b4fc68
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
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.Domain/SettingOptionResolveContributor.cs
0 → 100644
View file @
47b4fc68
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
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.Domain/Settings/WeChatPaySettingDefinitionProvider.cs
View file @
47b4fc68
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
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.Domain/Settings/WeChatPaySettings.cs
View file @
47b4fc68
...
...
@@ -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
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.Domain/UnifiedOrderFailedException.cs
0 → 100644
View file @
47b4fc68
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
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.Domain/WeChatPayPaymentServiceProvider.cs
0 → 100644
View file @
47b4fc68
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
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.HttpApi/EShopPaymentsWeChatPayHttpApiModule.cs
View file @
47b4fc68
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
)
...
...
modules/EasyAbp.EShop.Payments.WeChatPay/src/EasyAbp.EShop.Payments.WeChatPay.HttpApi/EasyAbp.EShop.Payments.WeChatPay.HttpApi.csproj
View file @
47b4fc68
...
...
@@ -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>
...
...
modules/EasyAbp.EShop.Payments/src/EasyAbp.EShop.Payments.Application/EasyAbp/EShop/Payments/Payments/EShopOrderPaymentAuthorizer.cs
View file @
47b4fc68
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
;
}
}
...
...
modules/EasyAbp.EShop.Payments/src/EasyAbp.EShop.Payments.Application/EasyAbp/EShop/Payments/Payments/PaymentAppService.cs
View file @
47b4fc68
...
...
@@ -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
())
...
...
modules/EasyAbp.EShop.Payments/src/EasyAbp.EShop.Payments.Domain/EasyAbp/EShop/Payments/EShopPaymentsDomainModule.cs
View file @
47b4fc68
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
>();
...
...
modules/EasyAbp.EShop.Payments/src/EasyAbp.EShop.Payments.Domain/EasyAbp/EShop/Payments/Payments/CurrencyNotSupportedException.cs
0 → 100644
View file @
47b4fc68
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
modules/EasyAbp.EShop.Payments/src/EasyAbp.EShop.Payments.Domain/EasyAbp/EShop/Payments/Payments/FreePaymentServiceProvider.cs
View file @
47b4fc68
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
.
Set
ExternalTradingCode
(
payment
.
Id
.
ToString
()
);
payment
.
Set
PayeeAccount
(
"None"
);
payment
.
SetExternalTradingCode
(
payment
.
Id
.
ToString
());
payment
.
CompletePayment
(
_clock
.
Now
);
return
await
_paymentRepository
.
UpdateAsync
(
payment
,
true
);
}
}
...
...
modules/EasyAbp.EShop.Payments/src/EasyAbp.EShop.Payments.Domain/EasyAbp/EShop/Payments/Payments/IPaymentServiceProvider.cs
View file @
47b4fc68
...
...
@@ -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
modules/EasyAbp.EShop.Payments/src/EasyAbp.EShop.Payments.Domain/EasyAbp/EShop/Payments/Payments/PayeeConfigurationMissingValueException.cs
0 → 100644
View file @
47b4fc68
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
modules/EasyAbp.EShop.Payments/src/EasyAbp.EShop.Payments.Domain/EasyAbp/EShop/Payments/Payments/Payment.cs
View file @
47b4fc68
...
...
@@ -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
)
...
...
modules/EasyAbp.EShop.Payments/src/EasyAbp.EShop.Payments.Domain/EasyAbp/EShop/Payments/Payments/PaymentHasAlreadyBeenCompletedException.cs
View file @
47b4fc68
...
...
@@ -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."
)
{
}
}
...
...
samples/EasyMall/aspnet-core/src/EasyMall.Domain/EasyMallDomainModule.cs
View file @
47b4fc68
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
));
}
}
}
samples/EasyMall/aspnet-core/src/EasyMall.EntityFrameworkCore.DbMigrations/Migrations/20200508090003_AddedUserIdToPayment.Designer.cs
0 → 100644
View file @
47b4fc68
This source diff could not be displayed because it is too large. You can
view the blob
instead.
samples/EasyMall/aspnet-core/src/EasyMall.EntityFrameworkCore.DbMigrations/Migrations/20200508090003_AddedUserIdToPayment.cs
0 → 100644
View file @
47b4fc68
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"
);
}
}
}
samples/EasyMall/aspnet-core/src/EasyMall.EntityFrameworkCore.DbMigrations/Migrations/EasyMallMigrationsDbContextModelSnapshot.cs
View file @
47b4fc68
...
...
@@ -279,6 +279,9 @@ namespace EasyMall.Migrations
.
HasColumnName
(
"TenantId"
)
.
HasColumnType
(
"uniqueidentifier"
);
b
.
Property
<
Guid
>(
"UserId"
)
.
HasColumnType
(
"uniqueidentifier"
);
b
.
HasKey
(
"Id"
);
b
.
ToTable
(
"PaymentsPayments"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment