payment_order_provider_snapshot_test.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. //go:build unit
  2. package service
  3. import (
  4. "context"
  5. "strconv"
  6. "testing"
  7. "github.com/Wei-Shaw/sub2api/internal/payment"
  8. "github.com/stretchr/testify/require"
  9. )
  10. func TestBuildPaymentOrderProviderSnapshot_ExcludesSensitiveConfig(t *testing.T) {
  11. t.Parallel()
  12. sel := &payment.InstanceSelection{
  13. InstanceID: "12",
  14. ProviderKey: payment.TypeWxpay,
  15. SupportedTypes: "wxpay,wxpay_direct",
  16. PaymentMode: "popup",
  17. Config: map[string]string{
  18. "privateKey": "secret",
  19. "apiV3Key": "secret-v3",
  20. "appId": "wx-app-id",
  21. },
  22. }
  23. snapshot := buildPaymentOrderProviderSnapshot(sel, CreateOrderRequest{})
  24. require.Equal(t, map[string]any{
  25. "schema_version": 2,
  26. "provider_instance_id": "12",
  27. "provider_key": payment.TypeWxpay,
  28. "payment_mode": "popup",
  29. "merchant_app_id": "wx-app-id",
  30. "currency": "CNY",
  31. }, snapshot)
  32. require.NotContains(t, snapshot, "config")
  33. require.NotContains(t, snapshot, "privateKey")
  34. require.NotContains(t, snapshot, "apiV3Key")
  35. require.NotContains(t, snapshot, "supported_types")
  36. require.NotContains(t, snapshot, "instance_name")
  37. require.NotContains(t, snapshot, "merchant_id")
  38. }
  39. func TestCreateOrderInTx_WritesProviderSnapshot(t *testing.T) {
  40. ctx := context.Background()
  41. client := newPaymentConfigServiceTestClient(t)
  42. user, err := client.User.Create().
  43. SetEmail("snapshot@example.com").
  44. SetPasswordHash("hash").
  45. SetUsername("snapshot-user").
  46. Save(ctx)
  47. require.NoError(t, err)
  48. instance, err := client.PaymentProviderInstance.Create().
  49. SetProviderKey(payment.TypeAlipay).
  50. SetName("Primary Alipay").
  51. SetConfig(`{"secretKey":"do-not-copy"}`).
  52. SetSupportedTypes("alipay,alipay_direct").
  53. SetPaymentMode("redirect").
  54. SetEnabled(true).
  55. Save(ctx)
  56. require.NoError(t, err)
  57. svc := &PaymentService{entClient: client}
  58. order, err := svc.createOrderInTx(
  59. ctx,
  60. CreateOrderRequest{
  61. UserID: user.ID,
  62. PaymentType: payment.TypeAlipay,
  63. OrderType: payment.OrderTypeBalance,
  64. ClientIP: "127.0.0.1",
  65. SrcHost: "app.example.com",
  66. },
  67. &User{
  68. ID: user.ID,
  69. Email: user.Email,
  70. Username: user.Username,
  71. },
  72. nil,
  73. &PaymentConfig{
  74. MaxPendingOrders: 3,
  75. OrderTimeoutMin: 30,
  76. },
  77. 88,
  78. 88,
  79. 0,
  80. 88,
  81. &payment.InstanceSelection{
  82. InstanceID: strconv.FormatInt(instance.ID, 10),
  83. ProviderKey: payment.TypeAlipay,
  84. SupportedTypes: "alipay,alipay_direct",
  85. PaymentMode: "redirect",
  86. Config: map[string]string{
  87. "secretKey": "do-not-copy",
  88. },
  89. },
  90. )
  91. require.NoError(t, err)
  92. require.Equal(t, strconv.FormatInt(instance.ID, 10), valueOrEmpty(order.ProviderInstanceID))
  93. require.Equal(t, payment.TypeAlipay, valueOrEmpty(order.ProviderKey))
  94. require.Equal(t, float64(2), order.ProviderSnapshot["schema_version"])
  95. require.Equal(t, strconv.FormatInt(instance.ID, 10), order.ProviderSnapshot["provider_instance_id"])
  96. require.Equal(t, payment.TypeAlipay, order.ProviderSnapshot["provider_key"])
  97. require.Equal(t, "redirect", order.ProviderSnapshot["payment_mode"])
  98. require.NotContains(t, order.ProviderSnapshot, "config")
  99. require.NotContains(t, order.ProviderSnapshot, "secretKey")
  100. require.NotContains(t, order.ProviderSnapshot, "supported_types")
  101. require.NotContains(t, order.ProviderSnapshot, "instance_name")
  102. }
  103. func TestBuildPaymentOrderProviderSnapshot_UsesWxpayJSAPIAppIDForOpenIDOrders(t *testing.T) {
  104. t.Parallel()
  105. snapshot := buildPaymentOrderProviderSnapshot(&payment.InstanceSelection{
  106. InstanceID: "88",
  107. ProviderKey: payment.TypeWxpay,
  108. Config: map[string]string{
  109. "appId": "wx-open-app",
  110. "mpAppId": "wx-mp-app",
  111. "mchId": "mch-88",
  112. },
  113. PaymentMode: "jsapi",
  114. }, CreateOrderRequest{OpenID: "openid-123"})
  115. require.Equal(t, "wx-mp-app", snapshot["merchant_app_id"])
  116. require.Equal(t, "mch-88", snapshot["merchant_id"])
  117. require.Equal(t, "CNY", snapshot["currency"])
  118. }
  119. func TestBuildPaymentOrderProviderSnapshot_IncludesAlipayMerchantIdentity(t *testing.T) {
  120. t.Parallel()
  121. snapshot := buildPaymentOrderProviderSnapshot(&payment.InstanceSelection{
  122. InstanceID: "21",
  123. ProviderKey: payment.TypeAlipay,
  124. Config: map[string]string{
  125. "appId": "alipay-app-21",
  126. "privateKey": "secret",
  127. },
  128. PaymentMode: "redirect",
  129. }, CreateOrderRequest{})
  130. require.Equal(t, "alipay-app-21", snapshot["merchant_app_id"])
  131. require.NotContains(t, snapshot, "privateKey")
  132. }
  133. func TestBuildPaymentOrderProviderSnapshot_IncludesEasyPayMerchantIdentity(t *testing.T) {
  134. t.Parallel()
  135. snapshot := buildPaymentOrderProviderSnapshot(&payment.InstanceSelection{
  136. InstanceID: "66",
  137. ProviderKey: payment.TypeEasyPay,
  138. Config: map[string]string{
  139. "pid": "easypay-merchant-66",
  140. "pkey": "secret",
  141. },
  142. PaymentMode: "popup",
  143. }, CreateOrderRequest{PaymentType: payment.TypeAlipay})
  144. require.Equal(t, "easypay-merchant-66", snapshot["merchant_id"])
  145. require.NotContains(t, snapshot, "pkey")
  146. }
  147. func TestBuildPaymentOrderProviderSnapshot_IncludesProviderCurrency(t *testing.T) {
  148. t.Parallel()
  149. stripeSnapshot := buildPaymentOrderProviderSnapshot(&payment.InstanceSelection{
  150. InstanceID: "77",
  151. ProviderKey: payment.TypeStripe,
  152. Config: map[string]string{
  153. "currency": "hkd",
  154. },
  155. }, CreateOrderRequest{})
  156. require.Equal(t, "HKD", stripeSnapshot["currency"])
  157. airwallexSnapshot := buildPaymentOrderProviderSnapshot(&payment.InstanceSelection{
  158. InstanceID: "78",
  159. ProviderKey: payment.TypeAirwallex,
  160. Config: map[string]string{
  161. "currency": "usd",
  162. "accountId": "acct-78",
  163. },
  164. }, CreateOrderRequest{})
  165. require.Equal(t, "USD", airwallexSnapshot["currency"])
  166. require.Equal(t, "acct-78", airwallexSnapshot["merchant_id"])
  167. }
  168. func valueOrEmpty(v *string) string {
  169. if v == nil {
  170. return ""
  171. }
  172. return *v
  173. }