react-native-hyperpay-sdk 1.0.4 → 1.0.6

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.
package/README.md CHANGED
@@ -82,6 +82,7 @@ HyperPay.init({
82
82
  mode: 'TestMode', // 'TestMode' | 'LiveMode'
83
83
  companyName: 'Your Company', // displayed in Apple Pay sheet (iOS only)
84
84
  supportedNetworks: ['visa', 'masterCard'], // Apple Pay supported networks (iOS only)
85
+ currencyCode: 'SAR', // ISO 4217 currency code, Apple Pay only (iOS only)
85
86
  });
86
87
  ```
87
88
 
@@ -95,6 +96,7 @@ HyperPay.init({
95
96
  | `mode` | `'TestMode' \| 'LiveMode'` | No | Payment environment — defaults to `'TestMode'` |
96
97
  | `companyName` | `string` | No | Merchant name displayed in the Apple Pay sheet as "Pay `<companyName>`" (iOS only) |
97
98
  | `supportedNetworks` | `SupportedNetworks[]` | No | Card networks accepted by Apple Pay (e.g. `'visa'`, `'masterCard'`, `'mada'`) (iOS only) |
99
+ | `currencyCode` | `string` | No | ISO 4217 currency code (e.g. `'SAR'`, `'USD'`) used for Apple Pay (iOS only) |
98
100
 
99
101
  ---
100
102
 
@@ -139,6 +141,7 @@ const result = await HyperPay.applePay({
139
141
  checkoutID: '<checkout_id_from_your_server>',
140
142
  companyName: 'Your Company', // optional — overrides init value
141
143
  amount: '100.00', // optional — displayed in the Apple Pay sheet
144
+ currencyCode: 'SAR', // optional — overrides init value
142
145
  });
143
146
 
144
147
  // result shape:
package/ios/HyperPay.h CHANGED
@@ -3,8 +3,9 @@
3
3
  #import <OPPWAMobile/OPPWAMobile.h>
4
4
  #import <React/RCTBridgeModule.h>
5
5
  #import <React/RCTEventEmitter.h>
6
+ #import <PassKit/PassKit.h>
6
7
 
7
- @interface HyperPay : RCTEventEmitter <RCTBridgeModule, OPPCheckoutProviderDelegate>
8
+ @interface HyperPay : RCTEventEmitter <RCTBridgeModule, OPPCheckoutProviderDelegate, PKPaymentAuthorizationViewControllerDelegate>
8
9
 
9
10
  @property(nonatomic, strong) OPPCheckoutProvider *checkoutProvider;
10
11
 
package/ios/HyperPay.m CHANGED
@@ -3,12 +3,21 @@
3
3
  #import "HyperPay.h"
4
4
  #import <React/RCTLog.h>
5
5
 
6
+ @interface HyperPay ()
7
+ @property (nonatomic, copy) NSString *checkoutID;
8
+ @property (nonatomic, copy) NSString *resourcePath;
9
+ @property (nonatomic, copy) NSString *redirectURL;
10
+ @property (nonatomic, copy) RCTPromiseResolveBlock _resolve;
11
+ @property (nonatomic, copy) RCTPromiseRejectBlock _reject;
12
+ @end
13
+
6
14
  @implementation HyperPay
7
15
 
8
16
  OPPPaymentProvider *provider;
9
17
  NSString *shopperResultURL = @"";
10
18
  NSString *merchantIdentifier = @"";
11
19
  NSString *countryCode = @"";
20
+ NSString *currencyCode = @"";
12
21
  NSString *mode=@"TestMode";
13
22
  NSArray *supportedNetworks;
14
23
  NSString *companyName=@"";
@@ -17,7 +26,7 @@ RCT_EXPORT_MODULE(HyperPay)
17
26
 
18
27
  -(instancetype)init
19
28
  {
20
-
29
+
21
30
  self = [super init];
22
31
  if (self) {
23
32
  provider = [OPPPaymentProvider paymentProviderWithMode:OPPProviderModeTest];
@@ -33,7 +42,6 @@ RCT_EXPORT_MODULE(HyperPay)
33
42
  React Native functions
34
43
  */
35
44
 
36
-
37
45
  RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(setup: (NSDictionary*)options) {
38
46
  shopperResultURL=[options valueForKey:@"shopperResultURL"];
39
47
  if ([options valueForKey:@"merchantIdentifier"])
@@ -42,6 +50,8 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(setup: (NSDictionary*)options) {
42
50
  companyName=[options valueForKey:@"companyName"];
43
51
  if ([options valueForKey:@"countryCode"])
44
52
  countryCode=[options valueForKey:@"countryCode"];
53
+ if ([options valueForKey:@"currencyCode"])
54
+ currencyCode=[options valueForKey:@"currencyCode"];
45
55
  if ([options valueForKey:@"supportedNetworks"])
46
56
  supportedNetworks=[options valueForKey:@"supportedNetworks"];
47
57
  if ([[options valueForKey:@"mode"] isEqual:@"LiveMode"])
@@ -70,13 +80,13 @@ RCT_EXPORT_METHOD(createPaymentTransaction: (NSDictionary*)options resolver:(RCT
70
80
 
71
81
  } else {
72
82
  params.shopperResultURL =shopperResultURL;
73
-
83
+
74
84
  OPPTransaction *transaction = [OPPTransaction transactionWithPaymentParams:params];
75
85
 
76
86
  [provider submitTransaction:transaction completionHandler:^(OPPTransaction * _Nonnull transaction, NSError * _Nullable error) {
77
87
  NSDictionary *transactionResult;
78
88
  if (transaction.type == OPPTransactionTypeAsynchronous) {
79
-
89
+
80
90
  transactionResult = @{
81
91
  @"redirectURL":transaction.redirectURL.absoluteString,
82
92
  @"status":@"pending",
@@ -99,44 +109,127 @@ RCT_EXPORT_METHOD(createPaymentTransaction: (NSDictionary*)options resolver:(RCT
99
109
  }
100
110
 
101
111
 
102
-
103
112
  RCT_EXPORT_METHOD(applePay:(NSDictionary*)params resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
113
+ dispatch_async(dispatch_get_main_queue(), ^{
114
+ self.checkoutID = [params valueForKey:@"checkoutID"];
115
+ self.resourcePath = nil;
116
+ self._resolve = resolve;
117
+ self._reject = reject;
118
+
119
+ NSString *merchant = [params valueForKey:@"merchantIdentifier"] ?: merchantIdentifier;
120
+ NSString *country = [params valueForKey:@"countryCode"] ?: countryCode;
121
+ NSString *currency = [params valueForKey:@"currencyCode"] ?: currencyCode;
122
+ NSString *company = [params valueForKey:@"companyName"] ?: companyName;
123
+ NSString *amountStr = [params valueForKey:@"amount"] ?: @"0.00";
124
+
125
+ PKPaymentRequest *paymentRequest = [OPPPaymentProvider paymentRequestWithMerchantIdentifier:merchant countryCode:country];
126
+ paymentRequest.currencyCode = currency;
127
+
128
+ NSArray *rawNetworks = [params valueForKey:@"supportedNetworks"] ?: supportedNetworks;
129
+ if (rawNetworks.count > 0 && [rawNetworks[0] isKindOfClass:[NSString class]]) {
130
+ NSMutableArray *mapped = [NSMutableArray array];
131
+ NSDictionary *networkMap = @{
132
+ @"visa": PKPaymentNetworkVisa,
133
+ @"mastercard": PKPaymentNetworkMasterCard,
134
+ @"amex": PKPaymentNetworkAmex,
135
+ @"mada": PKPaymentNetworkMada,
136
+ };
137
+ for (NSString *name in rawNetworks) {
138
+ PKPaymentNetwork net = networkMap[[name lowercaseString]];
139
+ if (net) [mapped addObject:net];
140
+ }
141
+ paymentRequest.supportedNetworks = mapped.count ? mapped : rawNetworks;
142
+ } else {
143
+ paymentRequest.supportedNetworks = rawNetworks;
144
+ }
145
+
146
+ NSDecimalNumber *amount = [NSDecimalNumber decimalNumberWithString:amountStr];
147
+ paymentRequest.paymentSummaryItems = @[ [PKPaymentSummaryItem summaryItemWithLabel:company amount:amount] ];
148
+
149
+ if (![OPPPaymentProvider canSubmitPaymentRequest:paymentRequest]) {
150
+ reject(@"applePay", @"Apple Pay is not supported on this device", nil);
151
+ return;
152
+ }
153
+
154
+ PKPaymentAuthorizationViewController *vc = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:paymentRequest];
155
+ if (!vc) {
156
+ reject(@"applePay", @"Failed to initialise Apple Pay sheet", nil);
157
+ return;
158
+ }
159
+ vc.delegate = self;
160
+
161
+ UIViewController *topVC = [UIApplication sharedApplication].delegate.window.rootViewController;
162
+ while (topVC.presentedViewController) topVC = topVC.presentedViewController;
163
+ [topVC presentViewController:vc animated:YES completion:^{
164
+ [self sendEventWithName:@"onProgress" body:@(YES)];
165
+ }];
166
+ });
167
+ }
168
+
169
+ - (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
170
+ didAuthorizePayment:(PKPayment *)payment
171
+ handler:(void (^)(PKPaymentAuthorizationResult *))completion
172
+ API_AVAILABLE(ios(11.0)) {
173
+ NSError *error = nil;
174
+ OPPApplePayPaymentParams *appleParams =
175
+ [[OPPApplePayPaymentParams alloc] initWithCheckoutID:self.checkoutID
176
+ tokenData:payment.token.paymentData
177
+ error:&error];
178
+ if (!appleParams) {
179
+ completion([[PKPaymentAuthorizationResult alloc]
180
+ initWithStatus:PKPaymentAuthorizationStatusFailure
181
+ errors:error ? @[error] : nil]);
182
+ return;
183
+ }
104
184
 
105
- OPPCheckoutSettings *checkoutSettings = [[OPPCheckoutSettings alloc] init];
106
- PKPaymentRequest *paymentRequest = [OPPPaymentProvider paymentRequestWithMerchantIdentifier:merchantIdentifier countryCode:countryCode];
107
- paymentRequest.supportedNetworks = supportedNetworks;
108
- // paymentRequest.merchantCapabilities = PKMerchantCapability3DS;
109
-
110
- if ([params valueForKey:@"companyName"]) {
111
- companyName = [params valueForKey:@"companyName"];
112
- }
113
-
114
- NSDecimalNumber *amount = [NSDecimalNumber decimalNumberWithMantissa:[[params valueForKey:@"amount"] intValue] exponent:-2 isNegative:NO];
115
- paymentRequest.paymentSummaryItems = @[ [PKPaymentSummaryItem summaryItemWithLabel:companyName amount:amount] ];
116
- checkoutSettings.shopperResultURL = shopperResultURL;
117
- checkoutSettings.applePayPaymentRequest = paymentRequest;
118
-
119
- self.checkoutProvider = [OPPCheckoutProvider checkoutProviderWithPaymentProvider:provider
120
- checkoutID:[params valueForKey:@"checkoutID"]
121
- settings:checkoutSettings];
122
- self.checkoutProvider.delegate = self;
123
-
124
- [self.checkoutProvider presentCheckoutWithPaymentBrand:@"APPLEPAY"
125
- loadingHandler:^(BOOL inProgress) {
126
- [self sendEventWithName:@"onProgress" body:@(inProgress)];
127
- } completionHandler:^(OPPTransaction * _Nullable transaction, NSError * _Nullable error) {
128
- if (error) {
129
- reject(@"applePay", error.localizedDescription, error);
130
- } else {
131
- if (transaction.redirectURL)
132
- resolve(@{@"redirectURL": transaction.redirectURL.absoluteString});
133
- else
134
- resolve(@{@"resourcePath": transaction.resourcePath});
135
- }
136
- } cancelHandler:^{
137
- reject(@"applePay", @"cancel", NULL);
138
- }];
185
+ appleParams.shopperResultURL = shopperResultURL;
186
+ OPPTransaction *transaction = [OPPTransaction transactionWithPaymentParams:appleParams];
139
187
 
188
+ __weak typeof(self) weakSelf = self;
189
+ [provider submitTransaction:transaction completionHandler:^(OPPTransaction *transaction, NSError *submitError) {
190
+ __strong typeof(weakSelf) _self = weakSelf;
191
+ if (!_self) {
192
+ completion([[PKPaymentAuthorizationResult alloc] initWithStatus:PKPaymentAuthorizationStatusFailure errors:nil]);
193
+ return;
194
+ }
195
+ if (submitError) {
196
+ completion([[PKPaymentAuthorizationResult alloc] initWithStatus:PKPaymentAuthorizationStatusFailure errors:nil]);
197
+ _self.resourcePath = nil;
198
+ _self._reject(@"applePay", submitError.localizedDescription, submitError);
199
+ _self._reject = nil;
200
+ _self._resolve = nil;
201
+ return;
202
+ }
203
+
204
+ _self.resourcePath = transaction.resourcePath;
205
+ _self.redirectURL = transaction.redirectURL.absoluteString;
206
+ completion([[PKPaymentAuthorizationResult alloc] initWithStatus:PKPaymentAuthorizationStatusSuccess errors:nil]);
207
+ }];
208
+ }
209
+
210
+ - (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller {
211
+ __weak typeof(self) weakSelf = self;
212
+ [controller dismissViewControllerAnimated:YES completion:^{
213
+ __strong typeof(weakSelf) _self = weakSelf;
214
+ if (!_self) return;
215
+
216
+ [_self sendEventWithName:@"onProgress" body:@(NO)];
217
+
218
+ if (!_self._resolve && !_self._reject) return;
219
+
220
+ if (_self.resourcePath || _self.redirectURL) {
221
+ _self._resolve(@{
222
+ @"resourcePath": _self.resourcePath ?: @"",
223
+ @"checkoutId": _self.checkoutID ?: @"",
224
+ @"redirectURL": _self.redirectURL ?: @"",
225
+ });
226
+ } else {
227
+ _self._reject(@"applePay", @"cancel", nil);
228
+ }
229
+ _self.resourcePath = nil;
230
+ _self._resolve = nil;
231
+ _self._reject = nil;
232
+ }];
140
233
  }
141
234
 
142
235
  #pragma mark - OPPCheckoutProviderDelegate
@@ -27,16 +27,27 @@ export interface Config {
27
27
 
28
28
  /**
29
29
  * set up supported payment networks for apple pay
30
- * @Platform IOS Only
30
+ * @Platform IOS Only
31
31
  */
32
32
  supportedNetworks?: Array<SupportedNetworks>
33
33
 
34
+ /**
35
+ * ISO 4217 currency code (e.g. "SAR", "USD"), Apple Pay only
36
+ * @Platform IOS Only
37
+ */
38
+ currencyCode?: string;
39
+
34
40
  }
35
41
 
36
42
  export type ApplyPayParams = {
37
43
  checkoutID:string;
38
44
  companyName?:string;
39
45
  amount?:string;
46
+ /**
47
+ * ISO 4217 currency code (e.g. "SAR", "USD") — overrides init value
48
+ * @Platform IOS Only
49
+ */
50
+ currencyCode?:string;
40
51
  }
41
52
 
42
53
  export type CreateTransactionParams = {
@@ -63,7 +74,8 @@ export default class HyperPay {
63
74
  * @param {CountryCodes} countryCode
64
75
  * @param {string} merchantIdentifier
65
76
  * @param {string} mode
66
- * @param {SupportedNetworks[]} supportedNetworks
77
+ * @param {SupportedNetworks[]} supportedNetworks
78
+ * @param {string} currencyCode
67
79
  * @returns Config
68
80
  */
69
81
 
@@ -72,7 +84,8 @@ export default class HyperPay {
72
84
  /**
73
85
  * @param {string} checkoutID
74
86
  * @param {string} companyName
75
- * @param {number} amount
87
+ * @param {number} amount
88
+ * @param {string} currencyCode
76
89
  * @param {(isProgress: boolean) => void} onProgress
77
90
  * @returns ```Promise<{ redirectURL?: string,
78
91
  resourcePath?: string}>```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-hyperpay-sdk",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "hyperpay",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",