@tapayadot/accept-react-native 1.0.0 → 1.2.0

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.
@@ -1,6 +1,8 @@
1
1
  import AcceptSDK
2
+ @_spi(AcceptDemo) import AcceptSDK
2
3
  import CoreLocation
3
4
  import ExpoModulesCore
5
+ import UIKit
4
6
 
5
7
  // MARK: - Records
6
8
 
@@ -32,11 +34,33 @@ final class CardPaymentResultRecord: Record {
32
34
  @Field var companyAddress1: String = ""
33
35
  @Field var companyAddress2: String? = nil
34
36
  @Field var companyCity: String = ""
35
- @Field var companyCountry: Int = 0
37
+ @Field var companyCountry: String = ""
36
38
  @Field var terminalId: String = ""
37
39
  @Field var authorizationCode: String? = nil
38
40
  @Field var brand: String? = nil
39
41
  @Field var reason: String? = nil
42
+ @Field var receiptUrl: String? = nil
43
+ @Field var refundToken: String? = nil
44
+ }
45
+
46
+ final class RefundIntentRecord: Record {
47
+ @Field var paymentToken: String = ""
48
+ @Field var refundToken: String? = nil
49
+ @Field var reason: String = "customerRequest"
50
+ }
51
+
52
+ final class RefundResultRecord: Record {
53
+ @Field var refundToken: String? = nil
54
+ @Field var status: String = ""
55
+ @Field var paymentMethod: String? = nil
56
+ @Field var requestedAmount: Int? = nil
57
+ @Field var requestedCurrency: String? = nil
58
+ @Field var settlementAmount: Int? = nil
59
+ @Field var settlementCurrency: String? = nil
60
+ @Field var fxRate: Double? = nil
61
+ @Field var refundReason: String = ""
62
+ @Field var createdAt: String? = nil
63
+ @Field var processedAt: String? = nil
40
64
  }
41
65
 
42
66
  final class BankTransferPaymentResultRecord: Record {
@@ -44,6 +68,32 @@ final class BankTransferPaymentResultRecord: Record {
44
68
  @Field var postponed: Bool = false
45
69
  @Field var receivedAt: String? = nil
46
70
  @Field var receivedFromIban: String? = nil
71
+ @Field var receiptUrl: String? = nil
72
+ }
73
+
74
+ final class GradientColorsRecord: Record {
75
+ @Field var start: String = ""
76
+ @Field var end: String = ""
77
+ }
78
+
79
+ final class AcceptColorThemeRecord: Record {
80
+ @Field var accent: String = ""
81
+ @Field var error: String = ""
82
+ @Field var warning: String = ""
83
+ @Field var success: String = ""
84
+ @Field var brandGradientColors: GradientColorsRecord? = nil
85
+ @Field var brandSubtleGradientColors: GradientColorsRecord? = nil
86
+ }
87
+
88
+ final class AcceptImageThemeRecord: Record {
89
+ @Field var brandLogo: String = ""
90
+ @Field var toolbarLogo: String = ""
91
+ @Field var solidLogo: String = ""
92
+ }
93
+
94
+ final class AcceptThemeConfigurationRecord: Record {
95
+ @Field var colors: AcceptColorThemeRecord? = nil
96
+ @Field var images: AcceptImageThemeRecord? = nil
47
97
  }
48
98
 
49
99
  final class KybPrefillDataRecord: Record {
@@ -98,20 +148,32 @@ public class AcceptSdkReactNativeModule: Module {
98
148
  public func definition() -> ModuleDefinition {
99
149
  Name("AcceptSdkReactNative")
100
150
 
101
- AsyncFunction("initialize") { (demo: Bool) async throws in
151
+ AsyncFunction("initialize") { (demo: Bool, theme: AcceptThemeConfigurationRecord?) async throws in
102
152
  do {
103
- try await Accept.initialize(environment: demo ? .sandbox : .production)
153
+ let themeConfig = try theme?.toAcceptThemeConfiguration() ?? .default
154
+ try await Accept.initialize(environment: demo ? .sandbox : .production, theme: themeConfig)
104
155
  } catch let error as AcceptSDKError {
105
- throw Exception(name: "AcceptSDKError", description: error.localizedDescription)
156
+ throw error.toException()
106
157
  }
107
- return true
158
+ }
159
+
160
+ AsyncFunction("setTheme") { (theme: AcceptThemeConfigurationRecord) async throws in
161
+ do {
162
+ try await Accept.setTheme(try theme.toAcceptThemeConfiguration())
163
+ } catch let error as AcceptSDKError {
164
+ throw error.toException()
165
+ }
166
+ }
167
+
168
+ AsyncFunction("setUiBehavior") { (_: [String: Any]) in
169
+ // No-op on iOS — UI behavior configuration is Android-only.
108
170
  }
109
171
 
110
172
  AsyncFunction("authenticate") { (token: String) async throws in
111
173
  do {
112
174
  try await Accept.authenticate(merchantToken: token)
113
175
  } catch let error as AcceptSDKError {
114
- throw Exception(name: "AcceptSDKError", description: error.localizedDescription)
176
+ throw error.toException()
115
177
  }
116
178
  return true
117
179
  }
@@ -134,7 +196,7 @@ public class AcceptSdkReactNativeModule: Module {
134
196
  do {
135
197
  try await Accept.logout()
136
198
  } catch let error as AcceptSDKError {
137
- throw Exception(name: "AcceptSDKError", description: error.localizedDescription)
199
+ throw error.toException()
138
200
  }
139
201
  return true
140
202
  }
@@ -144,11 +206,37 @@ public class AcceptSdkReactNativeModule: Module {
144
206
  try await Accept.presentKyb(prefilling: prefillData)
145
207
  }
146
208
 
209
+ AsyncFunction("getOnboardingStatus") { () async throws -> [String: Any] in
210
+ do {
211
+ let status = try await Accept.getOnboardingStatus()
212
+ return [
213
+ "isOnboarded": status.isOnboarded,
214
+ "paymentMethods": status.paymentMethods.map { pm in
215
+ [
216
+ "method": pm.method.toJsString(),
217
+ "status": pm.status.toJsString(),
218
+ ]
219
+ },
220
+ ]
221
+ } catch let error as AcceptSDKError {
222
+ throw error.toException()
223
+ }
224
+ }
225
+
226
+ AsyncFunction("getPaymentMethodStatus") { (method: String) async throws -> String in
227
+ do {
228
+ let status = try await Accept.getPaymentMethodStatus(for: try AcceptPaymentMethod.fromJsString(method))
229
+ return status.toJsString()
230
+ } catch let error as AcceptSDKError {
231
+ throw error.toException()
232
+ }
233
+ }
234
+
147
235
  AsyncFunction("requestLocationPermission") { () async throws -> Bool in
148
236
  do {
149
237
  try await Accept.requestLocationPermission()
150
238
  } catch let error as AcceptSDKError {
151
- throw Exception(name: "AcceptSDKError", description: error.localizedDescription)
239
+ throw error.toException()
152
240
  }
153
241
  return true
154
242
  }
@@ -157,7 +245,7 @@ public class AcceptSdkReactNativeModule: Module {
157
245
  do {
158
246
  try await Accept.pairWithCompanionApp()
159
247
  } catch let error as AcceptSDKError {
160
- throw Exception(name: "AcceptSDKError", description: error.localizedDescription)
248
+ throw error.toException()
161
249
  }
162
250
  }
163
251
 
@@ -169,7 +257,7 @@ public class AcceptSdkReactNativeModule: Module {
169
257
  do {
170
258
  try await Accept.presentCompanionAppSheet()
171
259
  } catch let error as AcceptSDKError {
172
- throw Exception(name: "AcceptSDKError", description: error.localizedDescription)
260
+ throw error.toException()
173
261
  }
174
262
  }
175
263
 
@@ -178,7 +266,7 @@ public class AcceptSdkReactNativeModule: Module {
178
266
  let status = try await Accept.getPaymentStatus(for: paymentIntentId)
179
267
  return try InfoResultSerializer.serialize(status)
180
268
  } catch let error as AcceptSDKError {
181
- throw Exception(name: "AcceptSDKError", description: error.localizedDescription)
269
+ throw error.toException()
182
270
  }
183
271
  }
184
272
 
@@ -187,7 +275,7 @@ public class AcceptSdkReactNativeModule: Module {
187
275
  let outcome = try await Accept.pay(intentRecord.toPaymentIntent())
188
276
  return outcome.toCardResult()
189
277
  } catch let error as AcceptSDKError {
190
- throw Exception(name: "AcceptSDKError", description: error.localizedDescription)
278
+ throw error.toException()
191
279
  }
192
280
  }
193
281
 
@@ -196,7 +284,7 @@ public class AcceptSdkReactNativeModule: Module {
196
284
  let outcome = try await Accept.pay(intentRecord.toPaymentIntent())
197
285
  return outcome.toBankTransferResult()
198
286
  } catch let error as AcceptSDKError {
199
- throw Exception(name: "AcceptSDKError", description: error.localizedDescription)
287
+ throw error.toException()
200
288
  }
201
289
  }
202
290
 
@@ -205,9 +293,150 @@ public class AcceptSdkReactNativeModule: Module {
205
293
  let outcome = try await Accept.pay(intentRecord.toPaymentIntent())
206
294
  return outcome.toBankTransferResult()
207
295
  } catch let error as AcceptSDKError {
208
- throw Exception(name: "AcceptSDKError", description: error.localizedDescription)
296
+ throw error.toException()
297
+ }
298
+ }
299
+
300
+ AsyncFunction("refund") { (intent: RefundIntentRecord) async throws -> RefundResultRecord in
301
+ do {
302
+ let refund = try await Accept.refund(
303
+ paymentToken: intent.paymentToken,
304
+ refundToken: intent.refundToken,
305
+ reason: try AcceptRefundReason.fromJsString(intent.reason)
306
+ )
307
+ return refund.toRecord()
308
+ } catch let error as AcceptSDKError {
309
+ throw error.toException()
310
+ }
311
+ }
312
+
313
+ AsyncFunction("cancelActivePayment") { () async throws in
314
+ do {
315
+ try await MainActor.run { try Accept.cancelActivePayment() }
316
+ } catch let error as AcceptSDKError {
317
+ throw error.toException()
209
318
  }
210
319
  }
320
+
321
+ AsyncFunction("enableDemoMode") { () async in
322
+ await Accept.enableDemoMode()
323
+ }
324
+
325
+ AsyncFunction("disableDemoMode") { () async in
326
+ await Accept.disableDemoMode()
327
+ }
328
+
329
+ AsyncFunction("isDemoMode") { () async -> Bool in
330
+ return await MainActor.run { Accept.isDemoMode }
331
+ }
332
+ }
333
+ }
334
+
335
+ // MARK: - Theme conversion
336
+
337
+ private extension AcceptThemeConfigurationRecord {
338
+ func toAcceptThemeConfiguration() throws -> AcceptThemeConfiguration {
339
+ var config = AcceptThemeConfiguration()
340
+ if let colorsRecord = colors {
341
+ config.colors = .local(try colorsRecord.toAcceptColorTheme())
342
+ }
343
+ if let imagesRecord = images {
344
+ config.images = .local(try imagesRecord.toAcceptImageTheme())
345
+ }
346
+ return config
347
+ }
348
+ }
349
+
350
+ private extension AcceptColorThemeRecord {
351
+ func toAcceptColorTheme() throws -> AcceptColorTheme {
352
+ AcceptColorTheme(
353
+ accent: try color(fromHex: accent),
354
+ error: try color(fromHex: error),
355
+ warning: try color(fromHex: warning),
356
+ success: try color(fromHex: success),
357
+ brandGradientColors: try brandGradientColors.map { GradientColors(start: try color(fromHex: $0.start), end: try color(fromHex: $0.end)) },
358
+ brandSubtleGradientColors: try brandSubtleGradientColors.map { GradientColors(start: try color(fromHex: $0.start), end: try color(fromHex: $0.end)) }
359
+ )
360
+ }
361
+ }
362
+
363
+ private extension AcceptImageThemeRecord {
364
+ func toAcceptImageTheme() throws -> AcceptImageTheme {
365
+ guard
366
+ let brandLogoData = Data(base64Encoded: brandLogo),
367
+ let brandLogoImage = UIImage(data: brandLogoData),
368
+ let toolbarLogoData = Data(base64Encoded: toolbarLogo),
369
+ let toolbarLogoImage = UIImage(data: toolbarLogoData),
370
+ let solidLogoData = Data(base64Encoded: solidLogo),
371
+ let solidLogoImage = UIImage(data: solidLogoData)
372
+ else {
373
+ throw Exception(name: "ThemeError", description: "Invalid base64 image data in AcceptImageTheme")
374
+ }
375
+ return AcceptImageTheme(brandLogo: brandLogoImage, toolbarLogo: toolbarLogoImage, solidLogo: solidLogoImage)
376
+ }
377
+ }
378
+
379
+ private func color(fromHex input: String) throws -> AcceptColor {
380
+ let hex = input.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
381
+ guard hex.count == 3 || hex.count == 6 || hex.count == 8 else {
382
+ throw Exception(name: "ThemeError", description: "Invalid hex color '\(input)'. Expected #RRGGBB or #AARRGGBB.")
383
+ }
384
+ var int: UInt64 = 0
385
+ guard Scanner(string: hex).scanHexInt64(&int) else {
386
+ throw Exception(name: "ThemeError", description: "Invalid hex color '\(input)'.")
387
+ }
388
+ let a, r, g, b: UInt64
389
+ switch hex.count {
390
+ case 3: (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
391
+ case 6: (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
392
+ case 8: (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
393
+ default: fatalError()
394
+ }
395
+ return AcceptColor(red: Double(r) / 255, green: Double(g) / 255, blue: Double(b) / 255, alpha: Double(a) / 255)
396
+ }
397
+
398
+ // MARK: - Error mapping
399
+
400
+ private extension AcceptSDKError {
401
+ func toException() -> Exception {
402
+ switch self {
403
+ case .notInitialized:
404
+ return Exception(name: "NotInitialized", description: errorDescription ?? "")
405
+ case .merchantNotAuthenticated:
406
+ return Exception(name: "MerchantNotAuthenticated", description: errorDescription ?? "")
407
+ case .locationPermissionsNotGranted:
408
+ return Exception(name: "LocationPermissionsNotGranted", description: errorDescription ?? "")
409
+ case .companionAppNotInstalled:
410
+ return Exception(name: "CompanionAppNotInstalled", description: errorDescription ?? "")
411
+ case .failedToAuthenticateMerchant:
412
+ return Exception(name: "FailedToAuthenticateMerchant", description: errorDescription ?? "")
413
+ case .failedToPresent:
414
+ return Exception(name: "FailedToPresent", description: errorDescription ?? "")
415
+ case .kybAlreadyInProgress:
416
+ return Exception(name: "KybAlreadyInProgress", description: errorDescription ?? "")
417
+ case .kybAlreadySubmitted:
418
+ return Exception(name: "KybAlreadySubmitted", description: errorDescription ?? "")
419
+ case .paymentAlreadyInProgress:
420
+ return Exception(name: "PaymentAlreadyInProgress", description: errorDescription ?? "")
421
+ case .unexpectedPaymentResult:
422
+ return Exception(name: "UnexpectedPaymentResult", description: errorDescription ?? "")
423
+ case .paymentNotFound:
424
+ return Exception(name: "PaymentNotFound", description: errorDescription ?? "")
425
+ case .refundConflict:
426
+ return Exception(name: "RefundConflict", description: errorDescription ?? "")
427
+ case .merchantOperationFailed:
428
+ return Exception(name: "MerchantOperationFailed", description: errorDescription ?? "")
429
+ case let .amountBelowMinimum(currency, minimum):
430
+ return Exception(name: "AmountBelowMinimum", description: "currency=\(currency) minimum=\(minimum)")
431
+ case let .amountAboveMaximum(currency, maximum):
432
+ return Exception(name: "AmountAboveMaximum", description: "currency=\(currency) maximum=\(maximum)")
433
+ case let .unknownCurrency(code):
434
+ return Exception(name: "UnknownCurrency", description: "code=\(code)")
435
+ case .noActivePayment:
436
+ return Exception(name: "NoActivePayment", description: errorDescription ?? "")
437
+ @unknown default:
438
+ return Exception(name: "AcceptSDKError", description: errorDescription ?? "")
439
+ }
211
440
  }
212
441
  }
213
442
 
@@ -221,11 +450,13 @@ private struct CardInfoResult: Encodable {
221
450
  let companyAddress1: String
222
451
  let companyAddress2: String
223
452
  let companyCity: String
224
- let companyCountry: Int
453
+ let companyCountry: String
225
454
  let terminalId: String
226
455
  let authorizationCode: String
227
456
  let brand: String
228
457
  let reason: String
458
+ let receiptUrl: String?
459
+ let refundToken: String?
229
460
  let type: String
230
461
  }
231
462
 
@@ -234,6 +465,7 @@ private struct BankTransferInfoResult: Encodable {
234
465
  let postponed: Bool
235
466
  let receivedAt: String
236
467
  let receivedFromIban: String
468
+ let receiptUrl: String?
237
469
  let type: String
238
470
  }
239
471
 
@@ -255,11 +487,13 @@ private enum InfoResultSerializer {
255
487
  companyAddress1: cardStatus.merchantDetails.addressLine1,
256
488
  companyAddress2: cardStatus.merchantDetails.addressLine2 ?? "",
257
489
  companyCity: cardStatus.merchantDetails.city,
258
- companyCountry: cardStatus.merchantDetails.country.rawValue,
490
+ companyCountry: cardStatus.merchantDetails.country,
259
491
  terminalId: cardStatus.terminalId,
260
492
  authorizationCode: cardStatus.details?.authorizationCode ?? "",
261
493
  brand: cardStatus.details?.brand.rawValue.uppercased() ?? "",
262
494
  reason: cardStatus.details?.issuerDeclineReason?.rawValue ?? "",
495
+ receiptUrl: cardStatus.receiptUrl?.absoluteString,
496
+ refundToken: cardStatus.refund?.refundToken,
263
497
  type: "card"
264
498
  ))
265
499
 
@@ -272,6 +506,7 @@ private enum InfoResultSerializer {
272
506
  postponed: bankStatus.details?.postponed ?? false,
273
507
  receivedAt: bankStatus.processedAt.map { ISO8601DateFormatter().string(from: $0) } ?? "",
274
508
  receivedFromIban: bankStatus.details?.bankAccountNumber ?? "",
509
+ receiptUrl: bankStatus.receiptUrl?.absoluteString,
275
510
  type: "sepa"
276
511
  ))
277
512
 
@@ -284,6 +519,7 @@ private enum InfoResultSerializer {
284
519
  postponed: bankStatus.details?.postponed ?? false,
285
520
  receivedAt: bankStatus.processedAt.map { ISO8601DateFormatter().string(from: $0) } ?? "",
286
521
  receivedFromIban: bankStatus.details?.bankAccountNumber ?? "",
522
+ receiptUrl: bankStatus.receiptUrl?.absoluteString,
287
523
  type: "certis"
288
524
  ))
289
525
 
@@ -336,37 +572,35 @@ private extension AcceptTransactionStatus {
336
572
  // MARK: - Payment intent conversion
337
573
 
338
574
  private extension CardPaymentIntentRecord {
339
- func toPaymentIntent() throws -> AcceptCardPaymentIntent {
340
- let requested = try AcceptCurrency.from(requestedCurrency)
341
- let settlement = try settlementCurrency.map { try AcceptCurrency.from($0) } ?? requested
342
- return AcceptCardPaymentIntent(id: paymentIntentId, amount: amount, requestedCurrency: requested, settlementCurrency: settlement)
575
+ func toPaymentIntent() -> AcceptCardPaymentIntent {
576
+ AcceptCardPaymentIntent(
577
+ id: paymentIntentId,
578
+ amount: amount,
579
+ requestedCurrency: requestedCurrency,
580
+ settlementCurrency: settlementCurrency ?? requestedCurrency
581
+ )
343
582
  }
344
583
  }
345
584
 
346
585
  private extension SepaPaymentIntentRecord {
347
- func toPaymentIntent() throws -> AcceptSepaPaymentIntent {
348
- let requested = try AcceptCurrency.from(requestedCurrency)
349
- let settlement = try settlementCurrency.map { try AcceptCurrency.from($0) } ?? requested
350
- return AcceptSepaPaymentIntent(id: paymentIntentId, amount: amount, requestedCurrency: requested, settlementCurrency: settlement)
586
+ func toPaymentIntent() -> AcceptSepaPaymentIntent {
587
+ AcceptSepaPaymentIntent(
588
+ id: paymentIntentId,
589
+ amount: amount,
590
+ requestedCurrency: requestedCurrency,
591
+ settlementCurrency: settlementCurrency ?? requestedCurrency
592
+ )
351
593
  }
352
594
  }
353
595
 
354
596
  private extension CertisPaymentIntentRecord {
355
- func toPaymentIntent() throws -> AcceptCertisPaymentIntent {
356
- let requested = try AcceptCurrency.from(requestedCurrency)
357
- let settlement = try settlementCurrency.map { try AcceptCurrency.from($0) } ?? requested
358
- return AcceptCertisPaymentIntent(id: paymentIntentId, amount: amount, requestedCurrency: requested, settlementCurrency: settlement)
359
- }
360
- }
361
-
362
- private extension AcceptCurrency {
363
- static func from(_ code: String) throws -> AcceptCurrency {
364
- switch code.uppercased() {
365
- case "CZK": return .czk
366
- case "EUR": return .eur
367
- case "GBP": return .gbp
368
- default: throw Exception(name: "InvalidCurrency", description: "Unsupported currency: \(code)")
369
- }
597
+ func toPaymentIntent() -> AcceptCertisPaymentIntent {
598
+ AcceptCertisPaymentIntent(
599
+ id: paymentIntentId,
600
+ amount: amount,
601
+ requestedCurrency: requestedCurrency,
602
+ settlementCurrency: settlementCurrency ?? requestedCurrency
603
+ )
370
604
  }
371
605
  }
372
606
 
@@ -385,11 +619,13 @@ private extension AcceptPaymentOutcome where Result == CardPaymentStatus {
385
619
  record.companyAddress1 = status.merchantDetails.addressLine1
386
620
  record.companyAddress2 = status.merchantDetails.addressLine2
387
621
  record.companyCity = status.merchantDetails.city
388
- record.companyCountry = status.merchantDetails.country.rawValue
622
+ record.companyCountry = status.merchantDetails.country
389
623
  record.terminalId = status.terminalId
390
624
  record.authorizationCode = status.details?.authorizationCode
391
625
  record.brand = status.details?.brand.rawValue.uppercased()
392
626
  record.reason = status.details?.issuerDeclineReason?.rawValue
627
+ record.receiptUrl = status.receiptUrl?.absoluteString
628
+ record.refundToken = status.refund?.refundToken
393
629
  }
394
630
  return record
395
631
  }
@@ -406,7 +642,104 @@ private extension AcceptPaymentOutcome where Result == BankTransferPaymentStatus
406
642
  record.postponed = status.details?.postponed ?? false
407
643
  record.receivedAt = status.processedAt.map { ISO8601DateFormatter().string(from: $0) }
408
644
  record.receivedFromIban = status.details?.bankAccountNumber
645
+ record.receiptUrl = status.receiptUrl?.absoluteString
646
+ }
647
+ return record
648
+ }
649
+ }
650
+
651
+ // MARK: - Onboarding status conversion
652
+
653
+ private extension AcceptPaymentMethod {
654
+ static func fromJsString(_ value: String) throws -> AcceptPaymentMethod {
655
+ switch value {
656
+ case "CARD": return .card
657
+ case "SEPA": return .sepaIct
658
+ case "CERTIS": return .certisCz
659
+ case "CRYPTO": return .crypto
660
+ default:
661
+ throw Exception(name: "InvalidPaymentMethod", description: "Unknown payment method: \(value)")
409
662
  }
663
+ }
664
+
665
+ func toJsString() -> String {
666
+ switch self {
667
+ case .card: return "CARD"
668
+ case .sepaIct: return "SEPA"
669
+ case .certisCz: return "CERTIS"
670
+ case .crypto: return "CRYPTO"
671
+ @unknown default: return "UNKNOWN"
672
+ }
673
+ }
674
+ }
675
+
676
+ private extension AcceptPaymentMethodStatus.Status {
677
+ func toJsString() -> String {
678
+ switch self {
679
+ case .notStarted: return "NOT_STARTED"
680
+ case .pending: return "PENDING"
681
+ case .active: return "ACTIVE"
682
+ case .attentionNeeded: return "ATTENTION_NEEDED"
683
+ case .actionRequired: return "ACTION_REQUIRED"
684
+ case .blocked: return "BLOCKED"
685
+ @unknown default: return "UNKNOWN"
686
+ }
687
+ }
688
+ }
689
+
690
+ // MARK: - Refund conversion
691
+
692
+ private extension AcceptRefundReason {
693
+ static func fromJsString(_ value: String) throws -> AcceptRefundReason {
694
+ switch value {
695
+ case "customerRequest": return .customerRequest
696
+ case "duplicate": return .duplicate
697
+ case "fraudulent": return .fraudulent
698
+ case "expiredCharge": return .expiredCharge
699
+ default:
700
+ throw Exception(name: "InvalidRefundReason", description: "Unknown refund reason: \(value)")
701
+ }
702
+ }
703
+
704
+ func toJsString() -> String {
705
+ switch self {
706
+ case .customerRequest: return "customerRequest"
707
+ case .duplicate: return "duplicate"
708
+ case .fraudulent: return "fraudulent"
709
+ case .expiredCharge: return "expiredCharge"
710
+ @unknown default: return "customerRequest"
711
+ }
712
+ }
713
+ }
714
+
715
+ private extension AcceptTransactionStatus {
716
+ func toJsString() -> String {
717
+ switch self {
718
+ case .pending: return "pending"
719
+ case .success: return "success"
720
+ case .cancelled: return "cancelled"
721
+ case .refunded: return "refunded"
722
+ case .failed: return "failed"
723
+ case .actionNeeded: return "actionNeeded"
724
+ @unknown default: return "pending"
725
+ }
726
+ }
727
+ }
728
+
729
+ private extension AcceptRefund {
730
+ func toRecord() -> RefundResultRecord {
731
+ let record = RefundResultRecord()
732
+ record.refundToken = refundToken
733
+ record.status = status.toJsString()
734
+ record.paymentMethod = paymentMethod.toJsString()
735
+ record.requestedAmount = requestedAmount
736
+ record.requestedCurrency = requestedCurrency
737
+ record.settlementAmount = settlementAmount
738
+ record.settlementCurrency = settlementCurrency
739
+ record.fxRate = fxRate
740
+ record.refundReason = refundReason.toJsString()
741
+ record.createdAt = ISO8601DateFormatter().string(from: createdAt)
742
+ record.processedAt = processedAt.map { ISO8601DateFormatter().string(from: $0) }
410
743
  return record
411
744
  }
412
745
  }
package/package.json CHANGED
@@ -1,18 +1,15 @@
1
1
  {
2
2
  "name": "@tapayadot/accept-react-native",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Accept SDK for React Native/Expo",
5
5
  "keywords": [
6
6
  "react-native",
7
7
  "expo",
8
- "accept-react-native",
9
- "AcceptSdkReactNative",
10
- "expo-module",
11
- "native-module",
12
8
  "payments",
13
9
  "tapaya",
14
10
  "terminal",
15
- "softpos"
11
+ "softpos",
12
+ "tap-to-pay"
16
13
  ],
17
14
  "homepage": "https://github.com/tapayadot/accept-react-native#readme",
18
15
  "repository": {
@@ -37,7 +34,15 @@
37
34
  "import": "./build/index.js",
38
35
  "require": "./build/index.js",
39
36
  "default": "./build/index.js"
40
- }
37
+ },
38
+ "./utils": {
39
+ "types": "./build/utils.d.ts",
40
+ "import": "./build/utils.js",
41
+ "require": "./build/utils.js",
42
+ "default": "./build/utils.js"
43
+ },
44
+ "./app.plugin": "./app.plugin.js",
45
+ "./app.plugin.js": "./app.plugin.js"
41
46
  },
42
47
  "files": [
43
48
  "build",
@@ -68,9 +73,19 @@
68
73
  },
69
74
  "peerDependencies": {
70
75
  "expo": "*",
76
+ "expo-asset": "*",
77
+ "expo-file-system": "*",
71
78
  "react": "*",
72
79
  "react-native": "*"
73
80
  },
81
+ "peerDependenciesMeta": {
82
+ "expo-asset": {
83
+ "optional": true
84
+ },
85
+ "expo-file-system": {
86
+ "optional": true
87
+ }
88
+ },
74
89
  "devDependencies": {
75
90
  "@expo/npm-proofread": "1.0.1",
76
91
  "@react-native-community/cli": "20.1.3",
@@ -23,8 +23,8 @@ function withAcceptSdkIos(config) {
23
23
  isa: "XCRemoteSwiftPackageReference",
24
24
  repositoryURL: `"${ACCEPT_SDK_IOS_REPO}"`,
25
25
  requirement: {
26
- kind: "branch",
27
- branch: "master",
26
+ kind: "exactVersion",
27
+ version: "1.2.2",
28
28
  },
29
29
  };
30
30
 
@@ -65,11 +65,6 @@ module.exports = function withMyModule(config) {
65
65
  {
66
66
  android: {
67
67
  minSdkVersion: 30,
68
- extraMavenRepos: [
69
- {
70
- url: "https://maven.pkg.github.com/tapayadot/accept-sdk-android",
71
- },
72
- ],
73
68
  },
74
69
  },
75
70
  ],