react-native-iap 8.5.3 → 8.6.2
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 +4 -20
- package/RNIap.podspec +33 -18
- package/android/build.gradle +137 -38
- package/android/gradle.properties +8 -0
- package/ios/RNIapIos-Bridging-Header.h +2 -0
- package/ios/RNIapIos.m +13 -0
- package/ios/RNIapIos.swift +84 -36
- package/ios/{RNIap.xcodeproj → RNIapIos.xcodeproj}/project.pbxproj +29 -116
- package/lib/commonjs/__test__/iap.test.js +21 -0
- package/lib/commonjs/__test__/iap.test.js.map +1 -0
- package/lib/commonjs/hooks/useIAP.js +78 -0
- package/lib/commonjs/hooks/useIAP.js.map +1 -0
- package/lib/commonjs/hooks/withIAPContext.js +92 -0
- package/lib/commonjs/hooks/withIAPContext.js.map +1 -0
- package/lib/commonjs/iap.js +577 -0
- package/lib/commonjs/iap.js.map +1 -0
- package/lib/commonjs/index.js +59 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/types/amazon.js +2 -0
- package/lib/commonjs/types/amazon.js.map +1 -0
- package/lib/commonjs/types/android.js +55 -0
- package/lib/commonjs/types/android.js.map +1 -0
- package/lib/commonjs/types/apple.js +165 -0
- package/lib/commonjs/types/apple.js.map +1 -0
- package/lib/commonjs/types/index.js +59 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/module/__test__/iap.test.js +17 -0
- package/lib/module/__test__/iap.test.js.map +1 -0
- package/lib/module/hooks/useIAP.js +68 -0
- package/lib/module/hooks/useIAP.js.map +1 -0
- package/lib/module/hooks/withIAPContext.js +76 -0
- package/lib/module/hooks/withIAPContext.js.map +1 -0
- package/lib/module/iap.js +488 -0
- package/lib/module/iap.js.map +1 -0
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/types/amazon.js +2 -0
- package/lib/module/types/amazon.js.map +1 -0
- package/lib/module/types/android.js +44 -0
- package/lib/module/types/android.js.map +1 -0
- package/lib/module/types/apple.js +153 -0
- package/lib/module/types/apple.js.map +1 -0
- package/lib/module/types/index.js +48 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/typescript/__test__/iap.test.d.ts +1 -0
- package/lib/typescript/hooks/useIAP.d.ts +22 -0
- package/lib/typescript/hooks/withIAPContext.d.ts +22 -0
- package/lib/typescript/iap.d.ts +195 -0
- package/lib/typescript/index.d.ts +5 -0
- package/lib/typescript/types/amazon.d.ts +23 -0
- package/lib/typescript/types/android.d.ts +47 -0
- package/lib/typescript/types/apple.d.ts +424 -0
- package/lib/typescript/types/index.d.ts +146 -0
- package/package.json +80 -47
- package/src/__test__/iap.test.ts +20 -0
- package/src/hooks/useIAP.ts +130 -0
- package/src/hooks/withIAPContext.tsx +160 -0
- package/src/iap.ts +686 -0
- package/src/index.ts +7 -0
- package/src/types/amazon.ts +23 -0
- package/src/types/android.ts +51 -0
- package/src/types/apple.ts +467 -0
- package/src/types/index.ts +185 -0
- package/.editorconfig +0 -10
- package/.flowconfig +0 -11
- package/.monolinterrc +0 -3
- package/.prettierignore +0 -6
- package/.swiftlint.yml +0 -11
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +0 -6
- package/android/gradlew +0 -160
- package/android/gradlew.bat +0 -90
- package/babel.config.js +0 -12
- package/index.ts +0 -5
- package/ios/RNIap.xcodeproj/xcshareddata/xcschemes/RNIap.xcscheme +0 -80
- package/jest.config.js +0 -190
- package/test/mocks/react-native-modules.js +0 -14
package/ios/RNIapIos.swift
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
//
|
|
2
|
-
// RNIapIos.swift
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// Created by Andres Aguilar on 9/8/21.
|
|
6
|
-
//
|
|
7
1
|
import React
|
|
8
2
|
import StoreKit
|
|
9
3
|
|
|
10
|
-
typealias
|
|
4
|
+
typealias RNIapIosPromise = (RCTPromiseResolveBlock, RCTPromiseRejectBlock)
|
|
5
|
+
|
|
6
|
+
public func debugMessage(_ object: Any...) {
|
|
7
|
+
#if DEBUG
|
|
8
|
+
for item in object {
|
|
9
|
+
print("[react-native-iap] \(item)")
|
|
10
|
+
}
|
|
11
|
+
#endif
|
|
12
|
+
}
|
|
11
13
|
|
|
12
14
|
// Based on https://stackoverflow.com/a/40135192/570612
|
|
13
15
|
extension Date {
|
|
@@ -32,7 +34,7 @@ extension SKProductsRequest {
|
|
|
32
34
|
|
|
33
35
|
@objc(RNIapIos)
|
|
34
36
|
class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver, SKProductsRequestDelegate {
|
|
35
|
-
private var promisesByKey: [String: [
|
|
37
|
+
private var promisesByKey: [String: [RNIapIosPromise]]
|
|
36
38
|
private var myQueue: DispatchQueue
|
|
37
39
|
private var hasListeners = false
|
|
38
40
|
private var pendingTransactionWithAutoFinish = false
|
|
@@ -44,7 +46,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
44
46
|
private var countPendingTransaction: Int?
|
|
45
47
|
|
|
46
48
|
override init() {
|
|
47
|
-
promisesByKey = [String: [
|
|
49
|
+
promisesByKey = [String: [RNIapIosPromise]]()
|
|
48
50
|
pendingTransactionWithAutoFinish = false
|
|
49
51
|
myQueue = DispatchQueue(label: "reject")
|
|
50
52
|
validProducts = [SKProduct]()
|
|
@@ -82,7 +84,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
func addPromise(forKey key: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
85
|
-
var promises: [
|
|
87
|
+
var promises: [RNIapIosPromise]? = promisesByKey[key]
|
|
86
88
|
|
|
87
89
|
if promises == nil {
|
|
88
90
|
promises = []
|
|
@@ -93,7 +95,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
func resolvePromises(forKey key: String?, value: Any?) {
|
|
96
|
-
let promises: [
|
|
98
|
+
let promises: [RNIapIosPromise]? = promisesByKey[key ?? ""]
|
|
97
99
|
|
|
98
100
|
if let promises = promises {
|
|
99
101
|
for tuple in promises {
|
|
@@ -137,7 +139,6 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
137
139
|
let canMakePayments = SKPaymentQueue.canMakePayments()
|
|
138
140
|
resolve(NSNumber(value: canMakePayments))
|
|
139
141
|
}
|
|
140
|
-
|
|
141
142
|
@objc public func endConnection(
|
|
142
143
|
_ resolve: @escaping RCTPromiseResolveBlock = { _ in },
|
|
143
144
|
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
|
|
@@ -145,7 +146,6 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
145
146
|
SKPaymentQueue.default().remove(self)
|
|
146
147
|
resolve(nil)
|
|
147
148
|
}
|
|
148
|
-
|
|
149
149
|
@objc public func getItems(
|
|
150
150
|
_ skus: [String],
|
|
151
151
|
resolve: @escaping RCTPromiseResolveBlock = { _ in },
|
|
@@ -162,7 +162,6 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
|
-
|
|
166
165
|
@objc public func getAvailableItems(
|
|
167
166
|
_ resolve: @escaping RCTPromiseResolveBlock = { _ in },
|
|
168
167
|
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
|
|
@@ -206,8 +205,10 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
206
205
|
"message": "Invalid product ID.",
|
|
207
206
|
"productId": sku
|
|
208
207
|
]
|
|
208
|
+
|
|
209
209
|
sendEvent(withName: "purchase-error", body: err)
|
|
210
210
|
}
|
|
211
|
+
|
|
211
212
|
reject("E_DEVELOPER_ERROR", "Invalid product ID.", nil)
|
|
212
213
|
}
|
|
213
214
|
}
|
|
@@ -220,7 +221,6 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
220
221
|
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
|
|
221
222
|
) {
|
|
222
223
|
var product: SKProduct?
|
|
223
|
-
|
|
224
224
|
let lockQueue = DispatchQueue(label: "validProducts")
|
|
225
225
|
lockQueue.sync {
|
|
226
226
|
for p in validProducts {
|
|
@@ -267,7 +267,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
267
267
|
resolve: @escaping RCTPromiseResolveBlock = { _ in },
|
|
268
268
|
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
|
|
269
269
|
) {
|
|
270
|
-
|
|
270
|
+
debugMessage("buyProductWithQuantityIOS")
|
|
271
271
|
var product: SKProduct?
|
|
272
272
|
let lockQueue = DispatchQueue(label: "validProducts")
|
|
273
273
|
lockQueue.sync {
|
|
@@ -278,7 +278,6 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
278
278
|
}
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
|
-
|
|
282
281
|
if let prod = product {
|
|
283
282
|
let payment = SKMutablePayment(product: prod)
|
|
284
283
|
payment.quantity = quantity
|
|
@@ -301,7 +300,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
301
300
|
_ resolve: @escaping RCTPromiseResolveBlock = { _ in },
|
|
302
301
|
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
|
|
303
302
|
) {
|
|
304
|
-
|
|
303
|
+
debugMessage("clear remaining Transactions. Call this before make a new transaction")
|
|
305
304
|
|
|
306
305
|
let pendingTrans = SKPaymentQueue.default().transactions
|
|
307
306
|
let countPendingTransaction = pendingTrans.count
|
|
@@ -319,11 +318,14 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
319
318
|
_ resolve: @escaping RCTPromiseResolveBlock = { _ in },
|
|
320
319
|
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
|
|
321
320
|
) {
|
|
322
|
-
|
|
321
|
+
debugMessage("clear valid products")
|
|
322
|
+
|
|
323
323
|
let lockQueue = DispatchQueue(label: "validProducts")
|
|
324
|
+
|
|
324
325
|
lockQueue.sync {
|
|
325
326
|
validProducts.removeAll()
|
|
326
327
|
}
|
|
328
|
+
|
|
327
329
|
resolve(nil)
|
|
328
330
|
}
|
|
329
331
|
|
|
@@ -331,7 +333,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
331
333
|
_ resolve: @escaping RCTPromiseResolveBlock = { _ in },
|
|
332
334
|
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
|
|
333
335
|
) {
|
|
334
|
-
|
|
336
|
+
debugMessage("get promoted product")
|
|
335
337
|
resolve((promotedProduct != nil) ? getProductObject(promotedProduct!) : nil)
|
|
336
338
|
}
|
|
337
339
|
|
|
@@ -340,7 +342,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
340
342
|
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
|
|
341
343
|
) {
|
|
342
344
|
if let promoPayment = promotedPayment {
|
|
343
|
-
|
|
345
|
+
debugMessage("buy promoted product")
|
|
344
346
|
SKPaymentQueue.default().add(promoPayment)
|
|
345
347
|
} else {
|
|
346
348
|
reject("E_DEVELOPER_ERROR", "Invalid product ID.", nil)
|
|
@@ -376,6 +378,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
376
378
|
) {
|
|
377
379
|
requestReceiptData(withBlock: false) { receiptData, _ in
|
|
378
380
|
var output: [AnyHashable] = []
|
|
381
|
+
|
|
379
382
|
if let receipt = receiptData {
|
|
380
383
|
let transactions = SKPaymentQueue.default().transactions
|
|
381
384
|
|
|
@@ -388,9 +391,11 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
388
391
|
"quantity": "\(item.payment.quantity)",
|
|
389
392
|
"transactionReceipt": receipt.base64EncodedString(options: [])
|
|
390
393
|
]
|
|
394
|
+
|
|
391
395
|
output.append(purchase)
|
|
392
396
|
}
|
|
393
397
|
}
|
|
398
|
+
|
|
394
399
|
resolve(output)
|
|
395
400
|
}
|
|
396
401
|
}
|
|
@@ -416,9 +421,10 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
416
421
|
for prod in response.products {
|
|
417
422
|
add(prod)
|
|
418
423
|
}
|
|
419
|
-
var items: [[String: Any?]] = [[:]]
|
|
420
424
|
|
|
425
|
+
var items: [[String: Any?]] = [[:]]
|
|
421
426
|
let lockQueue = DispatchQueue(label: "validProducts")
|
|
427
|
+
|
|
422
428
|
lockQueue.sync {
|
|
423
429
|
for product in validProducts {
|
|
424
430
|
items.append(getProductObject(product))
|
|
@@ -427,28 +433,34 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
427
433
|
|
|
428
434
|
resolvePromises(forKey: request.key, value: items)
|
|
429
435
|
}
|
|
436
|
+
|
|
430
437
|
// Add to valid products from Apple server response. Allowing getProducts, getSubscriptions call several times.
|
|
431
438
|
// Doesn't allow duplication. Replace new product.
|
|
432
439
|
func add(_ aProd: SKProduct) {
|
|
433
440
|
let lockQueue = DispatchQueue(label: "validProducts")
|
|
441
|
+
|
|
434
442
|
lockQueue.sync {
|
|
435
|
-
|
|
443
|
+
debugMessage("Add new object: \(aProd.productIdentifier)")
|
|
436
444
|
var delTar = -1
|
|
445
|
+
|
|
437
446
|
for k in 0..<validProducts.count {
|
|
438
447
|
let cur = validProducts[k]
|
|
439
448
|
if cur.productIdentifier == aProd.productIdentifier {
|
|
440
449
|
delTar = k
|
|
441
450
|
}
|
|
442
451
|
}
|
|
452
|
+
|
|
443
453
|
if delTar >= 0 {
|
|
444
454
|
validProducts.remove(at: delTar)
|
|
445
455
|
}
|
|
456
|
+
|
|
446
457
|
validProducts.append(aProd)
|
|
447
458
|
}
|
|
448
459
|
}
|
|
449
460
|
|
|
450
461
|
func request(_ request: SKRequest, didFailWithError error: Error) {
|
|
451
462
|
let nsError = error as NSError
|
|
463
|
+
|
|
452
464
|
if request is SKReceiptRefreshRequest {
|
|
453
465
|
if let unwrappedReceiptBlock = receiptBlock {
|
|
454
466
|
let standardError = NSError(domain: nsError.domain, code: 9, userInfo: nsError.userInfo)
|
|
@@ -473,21 +485,22 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
473
485
|
for transaction in transactions {
|
|
474
486
|
switch transaction.transactionState {
|
|
475
487
|
case .purchasing:
|
|
476
|
-
|
|
488
|
+
debugMessage("Purchase Started")
|
|
477
489
|
break
|
|
478
490
|
|
|
479
491
|
case .purchased:
|
|
480
|
-
|
|
492
|
+
debugMessage("Purchase Successful")
|
|
481
493
|
purchaseProcess(transaction)
|
|
482
494
|
break
|
|
483
495
|
|
|
484
496
|
case .restored:
|
|
485
|
-
|
|
497
|
+
debugMessage("Restored")
|
|
486
498
|
SKPaymentQueue.default().finishTransaction(transaction)
|
|
487
499
|
break
|
|
488
500
|
|
|
489
501
|
case .deferred:
|
|
490
|
-
|
|
502
|
+
debugMessage("Deferred (awaiting approval via parental controls, etc.)")
|
|
503
|
+
|
|
491
504
|
myQueue.sync(execute: { [self] in
|
|
492
505
|
if hasListeners {
|
|
493
506
|
let err = [
|
|
@@ -497,8 +510,10 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
497
510
|
"productId": transaction.payment.productIdentifier,
|
|
498
511
|
"quantity": "\(transaction.payment.quantity)"
|
|
499
512
|
]
|
|
513
|
+
|
|
500
514
|
sendEvent(withName: "purchase-error", body: err)
|
|
501
515
|
}
|
|
516
|
+
|
|
502
517
|
rejectPromises(
|
|
503
518
|
forKey: transaction.payment.productIdentifier,
|
|
504
519
|
code: "E_DEFERRED_PAYMENT",
|
|
@@ -507,10 +522,13 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
507
522
|
})
|
|
508
523
|
|
|
509
524
|
case .failed:
|
|
510
|
-
|
|
525
|
+
debugMessage("Purchase Failed")
|
|
526
|
+
|
|
511
527
|
SKPaymentQueue.default().finishTransaction(transaction)
|
|
528
|
+
|
|
512
529
|
myQueue.sync(execute: { [self] in
|
|
513
530
|
let nsError = transaction.error as NSError?
|
|
531
|
+
|
|
514
532
|
if hasListeners {
|
|
515
533
|
let code = nsError?.code
|
|
516
534
|
let responseCode = String(code ?? 0)
|
|
@@ -521,6 +539,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
521
539
|
"message": transaction.error?.localizedDescription,
|
|
522
540
|
"productId": transaction.payment.productIdentifier
|
|
523
541
|
]
|
|
542
|
+
|
|
524
543
|
sendEvent(withName: "purchase-error", body: err)
|
|
525
544
|
}
|
|
526
545
|
|
|
@@ -530,6 +549,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
530
549
|
message: nsError?.localizedDescription,
|
|
531
550
|
error: nsError)
|
|
532
551
|
})
|
|
552
|
+
|
|
533
553
|
break
|
|
534
554
|
}
|
|
535
555
|
}
|
|
@@ -537,6 +557,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
537
557
|
|
|
538
558
|
func finishTransaction(withIdentifier transactionIdentifier: String?) {
|
|
539
559
|
let queue = SKPaymentQueue.default()
|
|
560
|
+
|
|
540
561
|
for transaction in queue.transactions {
|
|
541
562
|
if transaction.transactionIdentifier == transactionIdentifier {
|
|
542
563
|
SKPaymentQueue.default().finishTransaction(transaction)
|
|
@@ -545,19 +566,21 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
545
566
|
}
|
|
546
567
|
|
|
547
568
|
func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
|
|
548
|
-
|
|
549
|
-
print("\n\n\n paymentQueueRestoreCompletedTransactionsFinished \n\n.")
|
|
569
|
+
debugMessage("PaymentQueueRestoreCompletedTransactionsFinished")
|
|
550
570
|
var items = [[String: Any?]]()
|
|
571
|
+
|
|
551
572
|
for transaction in queue.transactions {
|
|
552
573
|
if transaction.transactionState == .restored || transaction.transactionState == .purchased {
|
|
553
574
|
getPurchaseData(transaction) { restored in
|
|
554
575
|
if let restored = restored {
|
|
555
576
|
items.append(restored)
|
|
556
577
|
}
|
|
578
|
+
|
|
557
579
|
SKPaymentQueue.default().finishTransaction(transaction)
|
|
558
580
|
}
|
|
559
581
|
}
|
|
560
582
|
}
|
|
583
|
+
|
|
561
584
|
resolvePromises(forKey: "availableItems", value: items)
|
|
562
585
|
}
|
|
563
586
|
|
|
@@ -569,7 +592,8 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
569
592
|
message: error.localizedDescription,
|
|
570
593
|
error: error)
|
|
571
594
|
})
|
|
572
|
-
|
|
595
|
+
|
|
596
|
+
debugMessage("restoreCompletedTransactionsFailedWithError")
|
|
573
597
|
}
|
|
574
598
|
|
|
575
599
|
func purchaseProcess(_ transaction: SKPaymentTransaction) {
|
|
@@ -577,6 +601,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
577
601
|
SKPaymentQueue.default().finishTransaction(transaction)
|
|
578
602
|
pendingTransactionWithAutoFinish = false
|
|
579
603
|
}
|
|
604
|
+
|
|
580
605
|
getPurchaseData(transaction) { [self] purchase in
|
|
581
606
|
resolvePromises(forKey: transaction.payment.productIdentifier, value: purchase)
|
|
582
607
|
|
|
@@ -601,6 +626,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
601
626
|
"E_RECEIPT_FAILED",
|
|
602
627
|
"E_RECEIPT_FINISHED_FAILED"
|
|
603
628
|
]
|
|
629
|
+
|
|
604
630
|
guard let code = code else {
|
|
605
631
|
return descriptions[0]
|
|
606
632
|
}
|
|
@@ -608,6 +634,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
608
634
|
if code > descriptions.count - 1 || code < 0 { // Fix crash app without internet connection
|
|
609
635
|
return descriptions[0]
|
|
610
636
|
}
|
|
637
|
+
|
|
611
638
|
return descriptions[code]
|
|
612
639
|
}
|
|
613
640
|
|
|
@@ -629,7 +656,6 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
629
656
|
var countryCode: String? = ""
|
|
630
657
|
var periodNumberIOS = "0"
|
|
631
658
|
var periodUnitIOS = ""
|
|
632
|
-
|
|
633
659
|
var itemType = "iap"
|
|
634
660
|
|
|
635
661
|
if #available(iOS 11.2, tvOS 11.2, *) {
|
|
@@ -655,9 +681,11 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
655
681
|
// introductoryPrice = product.introductoryPrice != nil ? [NSString stringWithFormat:@"%@", product.introductoryPrice] : @"";
|
|
656
682
|
if product.introductoryPrice != nil {
|
|
657
683
|
formatter.locale = product.introductoryPrice?.priceLocale
|
|
684
|
+
|
|
658
685
|
if let price = product.introductoryPrice?.price {
|
|
659
686
|
introductoryPrice = formatter.string(from: price)
|
|
660
687
|
}
|
|
688
|
+
|
|
661
689
|
introductoryPriceAsAmountIOS = product.introductoryPrice?.price.stringValue ?? ""
|
|
662
690
|
|
|
663
691
|
switch product.introductoryPrice?.paymentMode {
|
|
@@ -772,15 +800,20 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
772
800
|
numberOfPeriods = "0"
|
|
773
801
|
break
|
|
774
802
|
}
|
|
803
|
+
|
|
775
804
|
switch discount.subscriptionPeriod.unit {
|
|
776
805
|
case .day:
|
|
777
806
|
subscriptionPeriods = "DAY"
|
|
807
|
+
|
|
778
808
|
case .week:
|
|
779
809
|
subscriptionPeriods = "WEEK"
|
|
810
|
+
|
|
780
811
|
case .month:
|
|
781
812
|
subscriptionPeriods = "MONTH"
|
|
813
|
+
|
|
782
814
|
case .year:
|
|
783
815
|
subscriptionPeriods = "YEAR"
|
|
816
|
+
|
|
784
817
|
default:
|
|
785
818
|
subscriptionPeriods = ""
|
|
786
819
|
}
|
|
@@ -809,10 +842,13 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
809
842
|
"paymentMode": paymendMode,
|
|
810
843
|
"subscriptionPeriod": subscriptionPeriods
|
|
811
844
|
]
|
|
845
|
+
|
|
812
846
|
mappedDiscounts.append(discountObj)
|
|
813
847
|
}
|
|
848
|
+
|
|
814
849
|
return mappedDiscounts
|
|
815
850
|
}
|
|
851
|
+
|
|
816
852
|
return nil
|
|
817
853
|
}
|
|
818
854
|
|
|
@@ -827,6 +863,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
827
863
|
"productId": transaction.payment.productIdentifier,
|
|
828
864
|
"transactionReceipt": receiptData?.base64EncodedString(options: [])
|
|
829
865
|
]
|
|
866
|
+
|
|
830
867
|
// originalTransaction is available for restore purchase and purchase of cancelled/expired subscriptions
|
|
831
868
|
if let originalTransaction = transaction.original {
|
|
832
869
|
purchase["originalTransactionDateIOS"] = originalTransaction.transactionDate?.millisecondsSince1970String
|
|
@@ -839,7 +876,8 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
839
876
|
}
|
|
840
877
|
|
|
841
878
|
func requestReceiptData(withBlock forceRefresh: Bool, withBlock block: @escaping (_ data: Data?, _ error: Error?) -> Void) {
|
|
842
|
-
|
|
879
|
+
debugMessage("requestReceiptDataWithBlock with force refresh: \(forceRefresh ? "YES" : "NO")")
|
|
880
|
+
|
|
843
881
|
if forceRefresh || isReceiptPresent() == false {
|
|
844
882
|
let refreshRequest = SKReceiptRefreshRequest()
|
|
845
883
|
refreshRequest.delegate = self
|
|
@@ -854,49 +892,59 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
854
892
|
func isReceiptPresent() -> Bool {
|
|
855
893
|
let receiptURL = Bundle.main.appStoreReceiptURL
|
|
856
894
|
var canReachError: Error?
|
|
895
|
+
|
|
857
896
|
do {
|
|
858
897
|
try _ = receiptURL?.checkResourceIsReachable()
|
|
859
898
|
} catch let error {
|
|
860
899
|
canReachError = error
|
|
861
900
|
}
|
|
901
|
+
|
|
862
902
|
return canReachError == nil
|
|
863
903
|
}
|
|
864
904
|
|
|
865
905
|
func receiptData() -> Data? {
|
|
866
906
|
let receiptURL = Bundle.main.appStoreReceiptURL
|
|
867
907
|
var receiptData: Data?
|
|
908
|
+
|
|
868
909
|
if let receiptURL = receiptURL {
|
|
869
910
|
do {
|
|
870
911
|
try receiptData = Data(contentsOf: receiptURL)
|
|
871
912
|
} catch _ {
|
|
872
913
|
}
|
|
873
914
|
}
|
|
915
|
+
|
|
874
916
|
return receiptData
|
|
875
917
|
}
|
|
876
918
|
|
|
877
919
|
func requestDidFinish(_ request: SKRequest) {
|
|
878
920
|
if request is SKReceiptRefreshRequest {
|
|
879
921
|
if isReceiptPresent() == true {
|
|
880
|
-
|
|
922
|
+
debugMessage("Receipt refreshed success")
|
|
923
|
+
|
|
881
924
|
if let receiptBlock = receiptBlock {
|
|
882
925
|
receiptBlock(receiptData(), nil)
|
|
883
926
|
}
|
|
884
927
|
} else if let receiptBlock = receiptBlock {
|
|
885
|
-
|
|
928
|
+
debugMessage("Finished but receipt refreshed failed")
|
|
929
|
+
|
|
886
930
|
let error = NSError(domain: "Receipt request finished but it failed!", code: 10, userInfo: nil)
|
|
887
931
|
receiptBlock(nil, error)
|
|
888
932
|
}
|
|
933
|
+
|
|
889
934
|
receiptBlock = nil
|
|
890
935
|
}
|
|
891
936
|
}
|
|
892
937
|
|
|
893
938
|
func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) {
|
|
894
|
-
|
|
939
|
+
debugMessage("removedTransactions")
|
|
940
|
+
|
|
895
941
|
guard var unwrappedCount = countPendingTransaction else {
|
|
896
942
|
return
|
|
897
943
|
}
|
|
944
|
+
|
|
898
945
|
if unwrappedCount > 0 {
|
|
899
946
|
unwrappedCount -= transactions.count
|
|
947
|
+
|
|
900
948
|
if unwrappedCount == 0 {
|
|
901
949
|
resolvePromises(forKey: "cleaningTransactions", value: nil)
|
|
902
950
|
countPendingTransaction = nil
|