@gmisoftware/react-native-pay 0.0.12 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/README.md +223 -220
  2. package/android/src/main/java/com/margelo/nitro/pay/GooglePayRequestBuilder.kt +45 -12
  3. package/android/src/main/java/com/margelo/nitro/pay/HybridPaymentHandler.kt +27 -8
  4. package/ios/HybridPaymentHandler.swift +116 -9
  5. package/lib/hooks/__tests__/usePaymentCheckout.integration.test.d.ts +1 -0
  6. package/lib/hooks/__tests__/usePaymentCheckout.integration.test.js +191 -0
  7. package/lib/hooks/usePaymentCheckout.d.ts +47 -3
  8. package/lib/hooks/usePaymentCheckout.js +6 -4
  9. package/lib/plugin/__tests__/index.test.d.ts +1 -0
  10. package/lib/plugin/__tests__/index.test.js +33 -0
  11. package/lib/plugin/__tests__/withApplePay.test.d.ts +1 -0
  12. package/lib/plugin/__tests__/withApplePay.test.js +58 -0
  13. package/lib/plugin/__tests__/withGooglePay.test.d.ts +1 -0
  14. package/lib/plugin/__tests__/withGooglePay.test.js +45 -0
  15. package/lib/plugin/withApplePay.d.ts +1 -0
  16. package/lib/plugin/withApplePay.js +19 -4
  17. package/lib/types/Payment.d.ts +2 -1
  18. package/lib/utils/__tests__/paymentHelpers.test.d.ts +1 -0
  19. package/lib/utils/__tests__/paymentHelpers.test.js +75 -0
  20. package/lib/utils/paymentHelpers.d.ts +1 -4
  21. package/lib/utils/paymentHelpers.js +2 -5
  22. package/nitrogen/generated/android/NitroPay+autolinking.cmake +1 -1
  23. package/nitrogen/generated/android/NitroPay+autolinking.gradle +1 -1
  24. package/nitrogen/generated/android/NitroPayOnLoad.cpp +1 -1
  25. package/nitrogen/generated/android/NitroPayOnLoad.hpp +1 -1
  26. package/nitrogen/generated/android/c++/JCNContact.hpp +1 -1
  27. package/nitrogen/generated/android/c++/JCNContactType.hpp +1 -1
  28. package/nitrogen/generated/android/c++/JCNLabeledEmailAddress.hpp +1 -1
  29. package/nitrogen/generated/android/c++/JCNLabeledPhoneNumber.hpp +1 -1
  30. package/nitrogen/generated/android/c++/JCNLabeledPostalAddress.hpp +1 -1
  31. package/nitrogen/generated/android/c++/JCNPhoneNumber.hpp +1 -1
  32. package/nitrogen/generated/android/c++/JCNPostalAddress.hpp +1 -1
  33. package/nitrogen/generated/android/c++/JFunc_void.hpp +1 -1
  34. package/nitrogen/generated/android/c++/JGooglePayButtonTheme.hpp +1 -1
  35. package/nitrogen/generated/android/c++/JGooglePayButtonType.hpp +1 -1
  36. package/nitrogen/generated/android/c++/JGooglePayEnvironment.hpp +1 -1
  37. package/nitrogen/generated/android/c++/JHybridGooglePayButtonSpec.cpp +1 -1
  38. package/nitrogen/generated/android/c++/JHybridGooglePayButtonSpec.hpp +1 -1
  39. package/nitrogen/generated/android/c++/JHybridPaymentHandlerSpec.cpp +1 -1
  40. package/nitrogen/generated/android/c++/JHybridPaymentHandlerSpec.hpp +1 -1
  41. package/nitrogen/generated/android/c++/JPKSecureElementPass.hpp +1 -1
  42. package/nitrogen/generated/android/c++/JPassActivationState.hpp +1 -1
  43. package/nitrogen/generated/android/c++/JPayServiceStatus.hpp +1 -1
  44. package/nitrogen/generated/android/c++/JPaymentItem.hpp +1 -1
  45. package/nitrogen/generated/android/c++/JPaymentItemType.hpp +1 -1
  46. package/nitrogen/generated/android/c++/JPaymentMethod.hpp +1 -1
  47. package/nitrogen/generated/android/c++/JPaymentMethodType.hpp +1 -1
  48. package/nitrogen/generated/android/c++/JPaymentNetwork.hpp +1 -1
  49. package/nitrogen/generated/android/c++/JPaymentRequest.hpp +10 -6
  50. package/nitrogen/generated/android/c++/JPaymentResult.hpp +1 -1
  51. package/nitrogen/generated/android/c++/JPaymentToken.hpp +1 -1
  52. package/nitrogen/generated/android/c++/views/JHybridGooglePayButtonStateUpdater.cpp +1 -1
  53. package/nitrogen/generated/android/c++/views/JHybridGooglePayButtonStateUpdater.hpp +1 -1
  54. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/CNContact.kt +1 -1
  55. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/CNContactType.kt +1 -1
  56. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/CNLabeledEmailAddress.kt +1 -1
  57. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/CNLabeledPhoneNumber.kt +1 -1
  58. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/CNLabeledPostalAddress.kt +1 -1
  59. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/CNPhoneNumber.kt +1 -1
  60. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/CNPostalAddress.kt +1 -1
  61. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/Func_void.kt +1 -1
  62. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/GooglePayButtonTheme.kt +1 -1
  63. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/GooglePayButtonType.kt +1 -1
  64. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/GooglePayEnvironment.kt +1 -1
  65. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/HybridGooglePayButtonSpec.kt +1 -1
  66. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/HybridPaymentHandlerSpec.kt +1 -1
  67. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/NitroPayOnLoad.kt +1 -1
  68. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/PKSecureElementPass.kt +1 -1
  69. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/PassActivationState.kt +1 -1
  70. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/PayServiceStatus.kt +1 -1
  71. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/PaymentItem.kt +1 -1
  72. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/PaymentItemType.kt +1 -1
  73. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/PaymentMethod.kt +1 -1
  74. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/PaymentMethodType.kt +1 -1
  75. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/PaymentNetwork.kt +1 -1
  76. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/PaymentRequest.kt +7 -4
  77. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/PaymentResult.kt +1 -1
  78. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/PaymentToken.kt +1 -1
  79. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/views/HybridGooglePayButtonManager.kt +1 -1
  80. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pay/views/HybridGooglePayButtonStateUpdater.kt +1 -1
  81. package/nitrogen/generated/ios/NitroPay+autolinking.rb +1 -1
  82. package/nitrogen/generated/ios/NitroPay-Swift-Cxx-Bridge.cpp +1 -1
  83. package/nitrogen/generated/ios/NitroPay-Swift-Cxx-Bridge.hpp +1 -1
  84. package/nitrogen/generated/ios/NitroPay-Swift-Cxx-Umbrella.hpp +1 -1
  85. package/nitrogen/generated/ios/NitroPayAutolinking.mm +1 -1
  86. package/nitrogen/generated/ios/NitroPayAutolinking.swift +1 -1
  87. package/nitrogen/generated/ios/c++/HybridApplePayButtonSpecSwift.cpp +1 -1
  88. package/nitrogen/generated/ios/c++/HybridApplePayButtonSpecSwift.hpp +1 -1
  89. package/nitrogen/generated/ios/c++/HybridPaymentHandlerSpecSwift.cpp +1 -1
  90. package/nitrogen/generated/ios/c++/HybridPaymentHandlerSpecSwift.hpp +1 -1
  91. package/nitrogen/generated/ios/c++/views/HybridApplePayButtonComponent.mm +1 -1
  92. package/nitrogen/generated/ios/swift/ApplePayButtonStyle.swift +1 -1
  93. package/nitrogen/generated/ios/swift/ApplePayButtonType.swift +1 -1
  94. package/nitrogen/generated/ios/swift/CNContact.swift +1 -1
  95. package/nitrogen/generated/ios/swift/CNContactType.swift +1 -1
  96. package/nitrogen/generated/ios/swift/CNLabeledEmailAddress.swift +1 -1
  97. package/nitrogen/generated/ios/swift/CNLabeledPhoneNumber.swift +1 -1
  98. package/nitrogen/generated/ios/swift/CNLabeledPostalAddress.swift +1 -1
  99. package/nitrogen/generated/ios/swift/CNPhoneNumber.swift +1 -1
  100. package/nitrogen/generated/ios/swift/CNPostalAddress.swift +1 -1
  101. package/nitrogen/generated/ios/swift/Func_void.swift +1 -1
  102. package/nitrogen/generated/ios/swift/Func_void_PaymentResult.swift +1 -1
  103. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +1 -1
  104. package/nitrogen/generated/ios/swift/GooglePayEnvironment.swift +1 -1
  105. package/nitrogen/generated/ios/swift/HybridApplePayButtonSpec.swift +1 -1
  106. package/nitrogen/generated/ios/swift/HybridApplePayButtonSpec_cxx.swift +1 -1
  107. package/nitrogen/generated/ios/swift/HybridPaymentHandlerSpec.swift +1 -1
  108. package/nitrogen/generated/ios/swift/HybridPaymentHandlerSpec_cxx.swift +1 -1
  109. package/nitrogen/generated/ios/swift/PKSecureElementPass.swift +1 -1
  110. package/nitrogen/generated/ios/swift/PassActivationState.swift +1 -1
  111. package/nitrogen/generated/ios/swift/PayServiceStatus.swift +1 -1
  112. package/nitrogen/generated/ios/swift/PaymentItem.swift +1 -1
  113. package/nitrogen/generated/ios/swift/PaymentItemType.swift +1 -1
  114. package/nitrogen/generated/ios/swift/PaymentMethod.swift +1 -1
  115. package/nitrogen/generated/ios/swift/PaymentMethodType.swift +1 -1
  116. package/nitrogen/generated/ios/swift/PaymentNetwork.swift +1 -1
  117. package/nitrogen/generated/ios/swift/PaymentRequest.swift +55 -6
  118. package/nitrogen/generated/ios/swift/PaymentResult.swift +1 -1
  119. package/nitrogen/generated/ios/swift/PaymentToken.swift +1 -1
  120. package/nitrogen/generated/shared/c++/ApplePayButtonStyle.hpp +1 -1
  121. package/nitrogen/generated/shared/c++/ApplePayButtonType.hpp +1 -1
  122. package/nitrogen/generated/shared/c++/CNContact.hpp +1 -1
  123. package/nitrogen/generated/shared/c++/CNContactType.hpp +1 -1
  124. package/nitrogen/generated/shared/c++/CNLabeledEmailAddress.hpp +1 -1
  125. package/nitrogen/generated/shared/c++/CNLabeledPhoneNumber.hpp +1 -1
  126. package/nitrogen/generated/shared/c++/CNLabeledPostalAddress.hpp +1 -1
  127. package/nitrogen/generated/shared/c++/CNPhoneNumber.hpp +1 -1
  128. package/nitrogen/generated/shared/c++/CNPostalAddress.hpp +1 -1
  129. package/nitrogen/generated/shared/c++/GooglePayButtonTheme.hpp +1 -1
  130. package/nitrogen/generated/shared/c++/GooglePayButtonType.hpp +1 -1
  131. package/nitrogen/generated/shared/c++/GooglePayEnvironment.hpp +1 -1
  132. package/nitrogen/generated/shared/c++/HybridApplePayButtonSpec.cpp +1 -1
  133. package/nitrogen/generated/shared/c++/HybridApplePayButtonSpec.hpp +1 -1
  134. package/nitrogen/generated/shared/c++/HybridGooglePayButtonSpec.cpp +1 -1
  135. package/nitrogen/generated/shared/c++/HybridGooglePayButtonSpec.hpp +1 -1
  136. package/nitrogen/generated/shared/c++/HybridPaymentHandlerSpec.cpp +1 -1
  137. package/nitrogen/generated/shared/c++/HybridPaymentHandlerSpec.hpp +1 -1
  138. package/nitrogen/generated/shared/c++/PKSecureElementPass.hpp +1 -1
  139. package/nitrogen/generated/shared/c++/PassActivationState.hpp +1 -1
  140. package/nitrogen/generated/shared/c++/PayServiceStatus.hpp +1 -1
  141. package/nitrogen/generated/shared/c++/PaymentItem.hpp +1 -1
  142. package/nitrogen/generated/shared/c++/PaymentItemType.hpp +1 -1
  143. package/nitrogen/generated/shared/c++/PaymentMethod.hpp +1 -1
  144. package/nitrogen/generated/shared/c++/PaymentMethodType.hpp +1 -1
  145. package/nitrogen/generated/shared/c++/PaymentNetwork.hpp +1 -1
  146. package/nitrogen/generated/shared/c++/PaymentRequest.hpp +10 -6
  147. package/nitrogen/generated/shared/c++/PaymentResult.hpp +1 -1
  148. package/nitrogen/generated/shared/c++/PaymentToken.hpp +1 -1
  149. package/nitrogen/generated/shared/c++/views/HybridApplePayButtonComponent.cpp +1 -1
  150. package/nitrogen/generated/shared/c++/views/HybridApplePayButtonComponent.hpp +1 -1
  151. package/nitrogen/generated/shared/c++/views/HybridGooglePayButtonComponent.cpp +1 -1
  152. package/nitrogen/generated/shared/c++/views/HybridGooglePayButtonComponent.hpp +1 -1
  153. package/package.json +21 -4
  154. package/src/hooks/__tests__/usePaymentCheckout.integration.test.ts +248 -0
  155. package/src/hooks/usePaymentCheckout.ts +68 -9
  156. package/src/plugin/__tests__/index.test.ts +37 -0
  157. package/src/plugin/__tests__/withApplePay.test.ts +83 -0
  158. package/src/plugin/__tests__/withGooglePay.test.ts +66 -0
  159. package/src/plugin/withApplePay.ts +34 -6
  160. package/src/types/Payment.ts +4 -1
  161. package/src/utils/__tests__/paymentHelpers.test.ts +127 -0
  162. package/src/utils/paymentHelpers.ts +30 -15
@@ -2,7 +2,7 @@
2
2
  /// PaymentRequest.hpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2025 Marc Rousavy @ Margelo
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #pragma once
@@ -41,7 +41,7 @@ namespace margelo::nitro::pay {
41
41
  */
42
42
  struct PaymentRequest {
43
43
  public:
44
- std::string merchantIdentifier SWIFT_PRIVATE;
44
+ std::optional<std::string> applePayMerchantIdentifier SWIFT_PRIVATE;
45
45
  std::optional<std::string> merchantName SWIFT_PRIVATE;
46
46
  std::string countryCode SWIFT_PRIVATE;
47
47
  std::string currencyCode SWIFT_PRIVATE;
@@ -52,13 +52,14 @@ namespace margelo::nitro::pay {
52
52
  std::optional<std::vector<PaymentItem>> shippingMethods SWIFT_PRIVATE;
53
53
  std::optional<bool> billingContactRequired SWIFT_PRIVATE;
54
54
  std::optional<bool> shippingContactRequired SWIFT_PRIVATE;
55
+ std::optional<std::string> googlePayMerchantId SWIFT_PRIVATE;
55
56
  std::optional<GooglePayEnvironment> googlePayEnvironment SWIFT_PRIVATE;
56
57
  std::optional<std::string> googlePayGateway SWIFT_PRIVATE;
57
58
  std::optional<std::string> googlePayGatewayMerchantId SWIFT_PRIVATE;
58
59
 
59
60
  public:
60
61
  PaymentRequest() = default;
61
- explicit PaymentRequest(std::string merchantIdentifier, std::optional<std::string> merchantName, std::string countryCode, std::string currencyCode, std::vector<PaymentItem> paymentItems, std::vector<std::string> merchantCapabilities, std::vector<std::string> supportedNetworks, std::optional<std::string> shippingType, std::optional<std::vector<PaymentItem>> shippingMethods, std::optional<bool> billingContactRequired, std::optional<bool> shippingContactRequired, std::optional<GooglePayEnvironment> googlePayEnvironment, std::optional<std::string> googlePayGateway, std::optional<std::string> googlePayGatewayMerchantId): merchantIdentifier(merchantIdentifier), merchantName(merchantName), countryCode(countryCode), currencyCode(currencyCode), paymentItems(paymentItems), merchantCapabilities(merchantCapabilities), supportedNetworks(supportedNetworks), shippingType(shippingType), shippingMethods(shippingMethods), billingContactRequired(billingContactRequired), shippingContactRequired(shippingContactRequired), googlePayEnvironment(googlePayEnvironment), googlePayGateway(googlePayGateway), googlePayGatewayMerchantId(googlePayGatewayMerchantId) {}
62
+ explicit PaymentRequest(std::optional<std::string> applePayMerchantIdentifier, std::optional<std::string> merchantName, std::string countryCode, std::string currencyCode, std::vector<PaymentItem> paymentItems, std::vector<std::string> merchantCapabilities, std::vector<std::string> supportedNetworks, std::optional<std::string> shippingType, std::optional<std::vector<PaymentItem>> shippingMethods, std::optional<bool> billingContactRequired, std::optional<bool> shippingContactRequired, std::optional<std::string> googlePayMerchantId, std::optional<GooglePayEnvironment> googlePayEnvironment, std::optional<std::string> googlePayGateway, std::optional<std::string> googlePayGatewayMerchantId): applePayMerchantIdentifier(applePayMerchantIdentifier), merchantName(merchantName), countryCode(countryCode), currencyCode(currencyCode), paymentItems(paymentItems), merchantCapabilities(merchantCapabilities), supportedNetworks(supportedNetworks), shippingType(shippingType), shippingMethods(shippingMethods), billingContactRequired(billingContactRequired), shippingContactRequired(shippingContactRequired), googlePayMerchantId(googlePayMerchantId), googlePayEnvironment(googlePayEnvironment), googlePayGateway(googlePayGateway), googlePayGatewayMerchantId(googlePayGatewayMerchantId) {}
62
63
  };
63
64
 
64
65
  } // namespace margelo::nitro::pay
@@ -71,7 +72,7 @@ namespace margelo::nitro {
71
72
  static inline margelo::nitro::pay::PaymentRequest fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
72
73
  jsi::Object obj = arg.asObject(runtime);
73
74
  return margelo::nitro::pay::PaymentRequest(
74
- JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "merchantIdentifier")),
75
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "applePayMerchantIdentifier")),
75
76
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "merchantName")),
76
77
  JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "countryCode")),
77
78
  JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "currencyCode")),
@@ -82,6 +83,7 @@ namespace margelo::nitro {
82
83
  JSIConverter<std::optional<std::vector<margelo::nitro::pay::PaymentItem>>>::fromJSI(runtime, obj.getProperty(runtime, "shippingMethods")),
83
84
  JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, "billingContactRequired")),
84
85
  JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, "shippingContactRequired")),
86
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "googlePayMerchantId")),
85
87
  JSIConverter<std::optional<margelo::nitro::pay::GooglePayEnvironment>>::fromJSI(runtime, obj.getProperty(runtime, "googlePayEnvironment")),
86
88
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "googlePayGateway")),
87
89
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, "googlePayGatewayMerchantId"))
@@ -89,7 +91,7 @@ namespace margelo::nitro {
89
91
  }
90
92
  static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::pay::PaymentRequest& arg) {
91
93
  jsi::Object obj(runtime);
92
- obj.setProperty(runtime, "merchantIdentifier", JSIConverter<std::string>::toJSI(runtime, arg.merchantIdentifier));
94
+ obj.setProperty(runtime, "applePayMerchantIdentifier", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.applePayMerchantIdentifier));
93
95
  obj.setProperty(runtime, "merchantName", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.merchantName));
94
96
  obj.setProperty(runtime, "countryCode", JSIConverter<std::string>::toJSI(runtime, arg.countryCode));
95
97
  obj.setProperty(runtime, "currencyCode", JSIConverter<std::string>::toJSI(runtime, arg.currencyCode));
@@ -100,6 +102,7 @@ namespace margelo::nitro {
100
102
  obj.setProperty(runtime, "shippingMethods", JSIConverter<std::optional<std::vector<margelo::nitro::pay::PaymentItem>>>::toJSI(runtime, arg.shippingMethods));
101
103
  obj.setProperty(runtime, "billingContactRequired", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.billingContactRequired));
102
104
  obj.setProperty(runtime, "shippingContactRequired", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.shippingContactRequired));
105
+ obj.setProperty(runtime, "googlePayMerchantId", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.googlePayMerchantId));
103
106
  obj.setProperty(runtime, "googlePayEnvironment", JSIConverter<std::optional<margelo::nitro::pay::GooglePayEnvironment>>::toJSI(runtime, arg.googlePayEnvironment));
104
107
  obj.setProperty(runtime, "googlePayGateway", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.googlePayGateway));
105
108
  obj.setProperty(runtime, "googlePayGatewayMerchantId", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.googlePayGatewayMerchantId));
@@ -113,7 +116,7 @@ namespace margelo::nitro {
113
116
  if (!nitro::isPlainObject(runtime, obj)) {
114
117
  return false;
115
118
  }
116
- if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "merchantIdentifier"))) return false;
119
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "applePayMerchantIdentifier"))) return false;
117
120
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "merchantName"))) return false;
118
121
  if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "countryCode"))) return false;
119
122
  if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "currencyCode"))) return false;
@@ -124,6 +127,7 @@ namespace margelo::nitro {
124
127
  if (!JSIConverter<std::optional<std::vector<margelo::nitro::pay::PaymentItem>>>::canConvert(runtime, obj.getProperty(runtime, "shippingMethods"))) return false;
125
128
  if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, "billingContactRequired"))) return false;
126
129
  if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, "shippingContactRequired"))) return false;
130
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "googlePayMerchantId"))) return false;
127
131
  if (!JSIConverter<std::optional<margelo::nitro::pay::GooglePayEnvironment>>::canConvert(runtime, obj.getProperty(runtime, "googlePayEnvironment"))) return false;
128
132
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "googlePayGateway"))) return false;
129
133
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "googlePayGatewayMerchantId"))) return false;
@@ -2,7 +2,7 @@
2
2
  /// PaymentResult.hpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2025 Marc Rousavy @ Margelo
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #pragma once
@@ -2,7 +2,7 @@
2
2
  /// PaymentToken.hpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2025 Marc Rousavy @ Margelo
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #pragma once
@@ -2,7 +2,7 @@
2
2
  /// HybridApplePayButtonComponent.cpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2025 Marc Rousavy @ Margelo
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #include "HybridApplePayButtonComponent.hpp"
@@ -2,7 +2,7 @@
2
2
  /// HybridApplePayButtonComponent.hpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2025 Marc Rousavy @ Margelo
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #pragma once
@@ -2,7 +2,7 @@
2
2
  /// HybridGooglePayButtonComponent.cpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2025 Marc Rousavy @ Margelo
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #include "HybridGooglePayButtonComponent.hpp"
@@ -2,7 +2,7 @@
2
2
  /// HybridGooglePayButtonComponent.hpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2025 Marc Rousavy @ Margelo
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #pragma once
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gmisoftware/react-native-pay",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "author": "gmi.software",
5
5
  "repository": {
6
6
  "type": "git",
@@ -10,15 +10,19 @@
10
10
  "module": "lib/index",
11
11
  "devDependencies": {
12
12
  "@react-native/eslint-config": "0.82.0",
13
- "@types/jest": "^29.5.12",
13
+ "@testing-library/react-native": "^13.3.3",
14
+ "@types/jest": "^30.0.0",
14
15
  "@types/react": "^19.1.03",
16
+ "babel-jest": "^30.2.0",
15
17
  "eslint": "^8.57.0",
16
18
  "eslint-config-prettier": "^9.1.0",
17
19
  "eslint-plugin-prettier": "^5.2.1",
20
+ "jest": "^30.2.0",
18
21
  "nitrogen": "*",
19
22
  "prettier": "^3.3.3",
20
- "typescript": "^5.8.3",
21
- "release-it": "^19.0.0"
23
+ "react-test-renderer": "19.1.0",
24
+ "release-it": "^19.0.0",
25
+ "typescript": "^5.8.3"
22
26
  },
23
27
  "peerDependencies": {
24
28
  "react": "*",
@@ -39,6 +43,16 @@
39
43
  "plugins": [
40
44
  "prettier"
41
45
  ],
46
+ "overrides": [
47
+ {
48
+ "files": [
49
+ "jest.setup.js"
50
+ ],
51
+ "env": {
52
+ "jest": true
53
+ }
54
+ }
55
+ ],
42
56
  "rules": {
43
57
  "prettier/prettier": [
44
58
  "warn",
@@ -105,6 +119,9 @@
105
119
  "postpack": "rm ./README.md",
106
120
  "postinstall": "tsc || exit 0;",
107
121
  "typecheck": "tsc --noEmit",
122
+ "test": "jest",
123
+ "test:watch": "jest --watch",
124
+ "test:ci": "jest --runInBand --ci",
108
125
  "clean": "rm -rf android/build node_modules/**/android/build lib",
109
126
  "lint": "eslint \"**/*.{js,ts,tsx}\" --fix",
110
127
  "lint-ci": "eslint \"**/*.{js,ts,tsx}\" -f @jamesacarr/github-actions",
@@ -0,0 +1,248 @@
1
+ import { act, renderHook, waitFor } from '@testing-library/react-native'
2
+
3
+ const mockPayServiceStatus = jest.fn()
4
+ const mockStartPayment = jest.fn()
5
+
6
+ jest.mock('react-native-nitro-modules', () => ({
7
+ NitroModules: {
8
+ createHybridObject: jest.fn(() => ({
9
+ payServiceStatus: (...args: any[]) => mockPayServiceStatus(...args),
10
+ startPayment: (...args: any[]) => mockStartPayment(...args),
11
+ })),
12
+ },
13
+ }))
14
+
15
+ import { usePaymentCheckout } from '../usePaymentCheckout'
16
+
17
+ describe('usePaymentCheckout integration', () => {
18
+ beforeEach(() => {
19
+ mockPayServiceStatus.mockReturnValue({
20
+ canMakePayments: true,
21
+ canSetupCards: true,
22
+ })
23
+ mockStartPayment.mockReset()
24
+ })
25
+
26
+ const renderCheckout = () => renderHook(() => usePaymentCheckout({}))
27
+
28
+ it('loads payment service status on mount', async () => {
29
+ const { result } = renderCheckout()
30
+
31
+ await waitFor(() => {
32
+ expect(result.current.isCheckingStatus).toBe(false)
33
+ })
34
+
35
+ expect(result.current.canMakePayments).toBe(true)
36
+ expect(result.current.canSetupCards).toBe(true)
37
+ })
38
+
39
+ it('falls back to unavailable status when status check fails', async () => {
40
+ mockPayServiceStatus.mockImplementationOnce(() => {
41
+ throw new Error('Native status failure')
42
+ })
43
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
44
+
45
+ const { result } = renderCheckout()
46
+
47
+ await waitFor(() => {
48
+ expect(result.current.isCheckingStatus).toBe(false)
49
+ })
50
+
51
+ expect(result.current.canMakePayments).toBe(false)
52
+ expect(result.current.canSetupCards).toBe(false)
53
+ expect(consoleSpy).toHaveBeenCalled()
54
+ consoleSpy.mockRestore()
55
+ })
56
+
57
+ it('manages cart operations and total correctly', async () => {
58
+ const { result } = renderCheckout()
59
+
60
+ await waitFor(() => {
61
+ expect(result.current.isCheckingStatus).toBe(false)
62
+ })
63
+
64
+ act(() => {
65
+ result.current.addItem('Coffee', 4.5)
66
+ result.current.addItems([
67
+ { label: 'Sandwich', amount: 8.25 },
68
+ { label: 'Tip', amount: 1.25, type: 'pending' },
69
+ ])
70
+ })
71
+
72
+ expect(result.current.items).toEqual([
73
+ { label: 'Coffee', amount: 4.5, type: 'final' },
74
+ { label: 'Sandwich', amount: 8.25, type: 'final' },
75
+ { label: 'Tip', amount: 1.25, type: 'pending' },
76
+ ])
77
+ expect(result.current.total).toBeCloseTo(14)
78
+
79
+ act(() => {
80
+ result.current.updateItem(0, { amount: 5 })
81
+ })
82
+ expect(result.current.items[0]?.amount).toBe(5)
83
+ expect(result.current.total).toBeCloseTo(14.5)
84
+
85
+ act(() => {
86
+ result.current.removeItem(1)
87
+ })
88
+ expect(result.current.items.map((item) => item.label)).toEqual([
89
+ 'Coffee',
90
+ 'Tip',
91
+ ])
92
+
93
+ act(() => {
94
+ result.current.clearItems()
95
+ })
96
+ expect(result.current.items).toEqual([])
97
+ expect(result.current.total).toBe(0)
98
+ })
99
+
100
+ it('provides default fallback payment item when cart is empty', () => {
101
+ const { result } = renderCheckout()
102
+
103
+ expect(result.current.paymentRequest.paymentItems).toEqual([
104
+ { label: 'Total', amount: 0, type: 'final' },
105
+ ])
106
+ expect(result.current.paymentRequest.countryCode).toBe('US')
107
+ expect(result.current.paymentRequest.currencyCode).toBe('USD')
108
+ expect(result.current.paymentRequest).not.toHaveProperty(
109
+ 'applePayMerchantIdentifier'
110
+ )
111
+ expect(result.current.paymentRequest).not.toHaveProperty('merchantName')
112
+ expect(result.current.paymentRequest).not.toHaveProperty(
113
+ 'googlePayMerchantId'
114
+ )
115
+ })
116
+
117
+ it('rejects startPayment when cart is empty', async () => {
118
+ const { result } = renderCheckout()
119
+
120
+ let paymentResult: any = 'not-called'
121
+ await act(async () => {
122
+ paymentResult = await result.current.startPayment()
123
+ })
124
+
125
+ expect(paymentResult).toBeNull()
126
+ expect(result.current.error?.message).toBe('Cart is empty')
127
+ expect(mockStartPayment).not.toHaveBeenCalled()
128
+ })
129
+
130
+ it('handles successful payments', async () => {
131
+ const nativeSuccess = { success: true, transactionId: 'tx_123' }
132
+ mockStartPayment.mockResolvedValueOnce(nativeSuccess)
133
+ const { result } = renderCheckout()
134
+
135
+ act(() => {
136
+ result.current.addItem('Coffee', 4.99)
137
+ })
138
+
139
+ let paymentResult: any = null
140
+ await act(async () => {
141
+ paymentResult = await result.current.startPayment()
142
+ })
143
+
144
+ expect(mockStartPayment).toHaveBeenCalledTimes(1)
145
+ expect(mockStartPayment).toHaveBeenCalledWith(
146
+ expect.objectContaining({
147
+ paymentItems: [{ label: 'Coffee', amount: 4.99, type: 'final' }],
148
+ })
149
+ )
150
+ expect(paymentResult).toEqual(nativeSuccess)
151
+ expect(result.current.result).toEqual(nativeSuccess)
152
+ expect(result.current.error).toBeNull()
153
+ expect(result.current.isProcessing).toBe(false)
154
+ })
155
+
156
+ it('sets an error when native payment response has success=false', async () => {
157
+ mockStartPayment.mockResolvedValueOnce({
158
+ success: false,
159
+ error: 'Declined by issuer',
160
+ })
161
+ const { result } = renderCheckout()
162
+
163
+ act(() => {
164
+ result.current.addItem('Order', 9.99)
165
+ })
166
+
167
+ await act(async () => {
168
+ await result.current.startPayment()
169
+ })
170
+
171
+ expect(result.current.error?.message).toBe('Declined by issuer')
172
+ expect(result.current.result).toEqual({
173
+ success: false,
174
+ error: 'Declined by issuer',
175
+ })
176
+ })
177
+
178
+ it('forwards Apple Pay override and Google Pay config when provided', async () => {
179
+ mockStartPayment.mockResolvedValueOnce({ success: true })
180
+
181
+ const { result } = renderHook(() =>
182
+ usePaymentCheckout({
183
+ applePayMerchantIdentifier: 'merchant.com.apple.override',
184
+ googlePayMerchantId: 'google-pay-merchant-id',
185
+ googlePayEnvironment: 'PRODUCTION',
186
+ googlePayGateway: 'stripe',
187
+ googlePayGatewayMerchantId: 'gateway-merchant-id',
188
+ })
189
+ )
190
+
191
+ act(() => {
192
+ result.current.addItem('Order', 12)
193
+ })
194
+
195
+ await act(async () => {
196
+ await result.current.startPayment()
197
+ })
198
+
199
+ expect(mockStartPayment).toHaveBeenCalledWith(
200
+ expect.objectContaining({
201
+ applePayMerchantIdentifier: 'merchant.com.apple.override',
202
+ googlePayMerchantId: 'google-pay-merchant-id',
203
+ googlePayEnvironment: 'PRODUCTION',
204
+ googlePayGateway: 'stripe',
205
+ googlePayGatewayMerchantId: 'gateway-merchant-id',
206
+ })
207
+ )
208
+ })
209
+
210
+ it('uses generic error for non-Error thrown values', async () => {
211
+ mockStartPayment.mockRejectedValueOnce('native crash')
212
+ const { result } = renderCheckout()
213
+
214
+ act(() => {
215
+ result.current.addItem('Order', 12)
216
+ })
217
+
218
+ let paymentResult: any = 'not-null'
219
+ await act(async () => {
220
+ paymentResult = await result.current.startPayment()
221
+ })
222
+
223
+ expect(paymentResult).toBeNull()
224
+ expect(result.current.error?.message).toBe('Payment processing failed')
225
+ })
226
+
227
+ it('resets transient checkout state', async () => {
228
+ mockStartPayment.mockResolvedValueOnce({ success: false, error: 'Failed' })
229
+ const { result } = renderCheckout()
230
+
231
+ act(() => {
232
+ result.current.addItem('Order', 3)
233
+ })
234
+ await act(async () => {
235
+ await result.current.startPayment()
236
+ })
237
+
238
+ expect(result.current.error).not.toBeNull()
239
+
240
+ act(() => {
241
+ result.current.reset()
242
+ })
243
+
244
+ expect(result.current.error).toBeNull()
245
+ expect(result.current.result).toBeNull()
246
+ expect(result.current.isProcessing).toBe(false)
247
+ })
248
+ })
@@ -11,17 +11,73 @@ import type {
11
11
  PayServiceStatus,
12
12
  GooglePayEnvironment,
13
13
  } from '../types'
14
- import { createPaymentItem, calculateTotal } from '../utils'
14
+ import {
15
+ createPaymentItem,
16
+ calculateTotal,
17
+ sanitizePaymentRequest,
18
+ } from '../utils'
15
19
 
20
+ /**
21
+ * Configuration for `usePaymentCheckout`.
22
+ */
16
23
  export interface UsePaymentCheckoutConfig {
17
- merchantIdentifier: string
24
+ /**
25
+ * Merchant name shown by payment providers that support displaying it.
26
+ * Used primarily by Google Pay.
27
+ */
18
28
  merchantName?: string
29
+
30
+ /**
31
+ * ISO 3166-1 alpha-2 country code for the transaction.
32
+ * Defaults to `'US'`.
33
+ */
19
34
  countryCode?: string
35
+
36
+ /**
37
+ * ISO 4217 currency code for all payment items.
38
+ * Defaults to `'USD'`.
39
+ */
20
40
  currencyCode?: string
41
+
42
+ /**
43
+ * Supported card networks for the payment sheet.
44
+ * Defaults to `['visa', 'mastercard', 'amex', 'discover']`.
45
+ */
21
46
  supportedNetworks?: string[]
47
+
48
+ /**
49
+ * Merchant capabilities passed to Apple Pay.
50
+ * Defaults to `['3DS']`.
51
+ */
22
52
  merchantCapabilities?: string[]
53
+
54
+ /**
55
+ * Optional Apple Pay Merchant ID override.
56
+ * When omitted, iOS reads the Merchant ID from the app entitlements.
57
+ */
58
+ applePayMerchantIdentifier?: string
59
+
60
+ /**
61
+ * Google Pay merchant ID used in Android production requests.
62
+ * Not needed for iOS.
63
+ */
64
+ googlePayMerchantId?: string
65
+
66
+ /**
67
+ * Google Pay environment for Android requests.
68
+ * Use `'TEST'` for sandbox flows and `'PRODUCTION'` for live payments.
69
+ */
23
70
  googlePayEnvironment?: GooglePayEnvironment
71
+
72
+ /**
73
+ * Payment gateway identifier for Google Pay tokenization.
74
+ * Examples include `'stripe'`, `'braintree'`, and `'adyen'`.
75
+ */
24
76
  googlePayGateway?: string
77
+
78
+ /**
79
+ * Merchant ID provided by your payment gateway for Google Pay tokenization.
80
+ */
25
81
  googlePayGatewayMerchantId?: string
26
82
  }
27
83
 
@@ -62,7 +118,8 @@ export interface UsePaymentCheckoutReturn {
62
118
  * - Payment processing
63
119
  * - State management
64
120
  *
65
- * @param config - Payment configuration
121
+ * @param config - Hook configuration including locale, supported networks,
122
+ * Apple Pay override, and Google Pay gateway settings.
66
123
  * @returns Complete payment checkout interface
67
124
  *
68
125
  * @example
@@ -79,9 +136,9 @@ export interface UsePaymentCheckoutReturn {
79
136
  * isProcessing,
80
137
  * error,
81
138
  * } = usePaymentCheckout({
82
- * merchantIdentifier: 'merchant.com.example',
83
139
  * currencyCode: 'USD',
84
140
  * countryCode: 'US',
141
+ * googlePayMerchantId: 'your_google_pay_merchant_id',
85
142
  * })
86
143
  *
87
144
  * // Add single item
@@ -142,30 +199,32 @@ export function usePaymentCheckout(
142
199
 
143
200
  const paymentRequest = useMemo<PaymentRequest>(() => {
144
201
  const {
145
- merchantIdentifier,
146
202
  merchantName,
147
203
  countryCode = 'US',
148
204
  currencyCode = 'USD',
149
205
  supportedNetworks = ['visa', 'mastercard', 'amex', 'discover'],
150
206
  merchantCapabilities = ['3DS'],
207
+ applePayMerchantIdentifier,
208
+ googlePayMerchantId,
151
209
  googlePayEnvironment,
152
210
  googlePayGateway,
153
211
  googlePayGatewayMerchantId,
154
212
  } = config
155
213
 
156
- return {
157
- merchantIdentifier,
214
+ return sanitizePaymentRequest({
158
215
  countryCode,
159
- merchantName,
160
216
  currencyCode,
161
217
  supportedNetworks,
162
218
  merchantCapabilities,
163
219
  paymentItems:
164
220
  items.length > 0 ? items : [createPaymentItem('Total', 0, 'final')],
221
+ applePayMerchantIdentifier,
222
+ merchantName,
223
+ googlePayMerchantId,
165
224
  googlePayEnvironment,
166
225
  googlePayGateway,
167
226
  googlePayGatewayMerchantId,
168
- }
227
+ })
169
228
  }, [config, items])
170
229
 
171
230
  // Cart operations
@@ -0,0 +1,37 @@
1
+ const mockWithGooglePay = jest.fn((config, _props) => ({
2
+ ...config,
3
+ googlePay: true,
4
+ }))
5
+ const mockWithApplePay = jest.fn((config, _props) => ({
6
+ ...config,
7
+ applePay: true,
8
+ }))
9
+
10
+ jest.mock('../withGooglePay', () => ({
11
+ withGooglePay: (config: any, props: any) => mockWithGooglePay(config, props),
12
+ }))
13
+
14
+ jest.mock('../withApplePay', () => ({
15
+ withApplePay: (config: any, props: any) => mockWithApplePay(config, props),
16
+ }))
17
+
18
+ import withReactNativePay from '../index'
19
+
20
+ describe('withReactNativePay', () => {
21
+ it('applies Google Pay and Apple Pay plugins in order', () => {
22
+ const inputConfig = { name: 'my-app' }
23
+ const props = {
24
+ merchantIdentifier: 'merchant.com.test',
25
+ enableGooglePay: true,
26
+ }
27
+
28
+ const result = withReactNativePay(inputConfig as any, props)
29
+
30
+ expect(mockWithGooglePay).toHaveBeenCalledWith(inputConfig, props)
31
+ expect(mockWithApplePay).toHaveBeenCalledWith(
32
+ { name: 'my-app', googlePay: true },
33
+ props
34
+ )
35
+ expect(result).toEqual({ name: 'my-app', googlePay: true, applePay: true })
36
+ })
37
+ })