feat: add Airwallex payments and multi-currency support

This commit is contained in:
shaw
2026-05-11 11:17:26 +08:00
parent dbc8ae658c
commit b23055af5b
65 changed files with 3164 additions and 162 deletions
+28 -5
View File
@@ -226,10 +226,11 @@ func (s *PaymentService) PrepareRefund(ctx context.Context, oid int64, amt float
if amt <= 0 {
amt = o.Amount
}
if amt-o.Amount > amountToleranceCNY {
orderCurrency := PaymentOrderCurrency(o)
if amt-o.Amount > paymentAmountToleranceForCurrency(orderCurrency) {
return nil, nil, infraerrors.BadRequest("REFUND_AMOUNT_EXCEEDED", "refund amount exceeds recharge")
}
ga := calculateGatewayRefundAmount(o.Amount, o.PayAmount, amt)
ga := calculateGatewayRefundAmount(o.Amount, o.PayAmount, amt, orderCurrency)
rr := strings.TrimSpace(reason)
if rr == "" && o.RefundRequestReason != nil {
rr = *o.RefundRequestReason
@@ -339,13 +340,35 @@ func (s *PaymentService) gwRefund(ctx context.Context, p *RefundPlan) error {
})
return err
}
_, err = prov.Refund(ctx, payment.RefundRequest{
resp, err := prov.Refund(ctx, payment.RefundRequest{
TradeNo: p.Order.PaymentTradeNo,
OrderID: p.Order.OutTradeNo,
Amount: strconv.FormatFloat(p.GatewayAmount, 'f', 2, 64),
Amount: formatGatewayRefundAmount(p.GatewayAmount, p.Order),
Reason: p.Reason,
})
return err
if err != nil {
return err
}
return validateRefundProviderResponse(resp)
}
func formatGatewayRefundAmount(amount float64, order *dbent.PaymentOrder) string {
return payment.FormatAmountForCurrency(amount, PaymentOrderCurrency(order))
}
func validateRefundProviderResponse(resp *payment.RefundResponse) error {
if resp == nil {
return fmt.Errorf("payment refund response missing")
}
status := strings.TrimSpace(resp.Status)
switch status {
case payment.ProviderStatusSuccess, payment.ProviderStatusRefunded, payment.ProviderStatusPending:
return nil
case payment.ProviderStatusFailed:
return fmt.Errorf("payment refund failed: status %s", status)
default:
return fmt.Errorf("payment refund returned unknown status: %s", status)
}
}
// getRefundProvider creates a provider using the order's original instance config.