A lightweight iOS library for In-App Purchases

Related tags

Payments RMStore
Overview

#RMStore

CocoaPods Version Platform Build Status Join the chat at https://gitter.im/robotmedia/RMStore

A lightweight iOS library for In-App Purchases.

RMStore adds blocks and notifications to StoreKit, plus receipt verification, content downloads and transaction persistence. All in one class without external dependencies. Purchasing a product is as simple as:

[[RMStore defaultStore] addPayment:productID success:^(SKPaymentTransaction *transaction) {
    NSLog(@"Purchased!");
} failure:^(SKPaymentTransaction *transaction, NSError *error) {
    NSLog(@"Something went wrong");
}];

##Installation

Using CocoaPods:

pod 'RMStore', '~> 0.7'

Or add the files from the RMStore directory if you're doing it manually.

Check out the wiki for more options.

##StoreKit with blocks

RMStore adds blocks to all asynchronous StoreKit operations.

###Requesting products

NSSet *products = [NSSet setWithArray:@[@"fabulousIdol", @"rootBeer", @"rubberChicken"]];
[[RMStore defaultStore] requestProducts:products success:^(NSArray *products, NSArray *invalidProductIdentifiers) {
    NSLog(@"Products loaded");
} failure:^(NSError *error) {
    NSLog(@"Something went wrong");
}];

###Add payment

[[RMStore defaultStore] addPayment:@"waxLips" success:^(SKPaymentTransaction *transaction) {
    NSLog(@"Product purchased");
} failure:^(SKPaymentTransaction *transaction, NSError *error) {
    NSLog(@"Something went wrong");
}];

###Restore transactions

[[RMStore defaultStore] restoreTransactionsOnSuccess:^(NSArray *transactions){
    NSLog(@"Transactions restored");
} failure:^(NSError *error) {
    NSLog(@"Something went wrong");
}];

###Refresh receipt (iOS 7+ only)

[[RMStore defaultStore] refreshReceiptOnSuccess:^{
    NSLog(@"Receipt refreshed");
} failure:^(NSError *error) {
    NSLog(@"Something went wrong");
}];

##Notifications

RMStore sends notifications of StoreKit related events and extends NSNotification to provide relevant information. To receive them, implement the desired methods of the RMStoreObserver protocol and add the observer to RMStore.

###Adding and removing the observer

[[RMStore defaultStore] addStoreObserver:self];
...
[[RMStore defaultStore] removeStoreObserver:self];

###Products request notifications

- (void)storeProductsRequestFailed:(NSNotification*)notification
{
    NSError *error = notification.rm_storeError;
}

- (void)storeProductsRequestFinished:(NSNotification*)notification
{
    NSArray *products = notification.rm_products;
    NSArray *invalidProductIdentifiers = notification.rm_invalidProductIdentififers;
}

###Payment transaction notifications

Payment transaction notifications are sent after a payment has been requested or for each restored transaction.

- (void)storePaymentTransactionFinished:(NSNotification*)notification
{
    NSString *productIdentifier = notification.rm_productIdentifier;
    SKPaymentTransaction *transaction = notification.rm_transaction;
}

- (void)storePaymentTransactionFailed:(NSNotification*)notification
{
    NSError *error = notification.rm_storeError;
    NSString *productIdentifier = notification.rm_productIdentifier;
    SKPaymentTransaction *transaction = notification.rm_transaction;
}

// iOS 8+ only

- (void)storePaymentTransactionDeferred:(NSNotification*)notification
{
    NSString *productIdentifier = notification.rm_productIdentifier;
    SKPaymentTransaction *transaction = notification.rm_transaction;
}

###Restore transactions notifications

- (void)storeRestoreTransactionsFailed:(NSNotification*)notification;
{
    NSError *error = notification.rm_storeError;
}

- (void)storeRestoreTransactionsFinished:(NSNotification*)notification
{
	NSArray *transactions = notification.rm_transactions;
}

###Download notifications (iOS 6+ only)

For Apple-hosted and self-hosted downloads:

- (void)storeDownloadFailed:(NSNotification*)notification
{
    SKDownload *download = notification.rm_storeDownload; // Apple-hosted only
    NSString *productIdentifier = notification.rm_productIdentifier;
    SKPaymentTransaction *transaction = notification.rm_transaction;
    NSError *error = notification.rm_storeError;
}

- (void)storeDownloadFinished:(NSNotification*)notification;
{
    SKDownload *download = notification.rm_storeDownload; // Apple-hosted only
    NSString *productIdentifier = notification.rm_productIdentifier;
    SKPaymentTransaction *transaction = notification.rm_transaction;
}

- (void)storeDownloadUpdated:(NSNotification*)notification
{
    SKDownload *download = notification.rm_storeDownload; // Apple-hosted only
    NSString *productIdentifier = notification.rm_productIdentifier;
    SKPaymentTransaction *transaction = notification.rm_transaction;
    float progress = notification.rm_downloadProgress;
}

Only for Apple-hosted downloads:

- (void)storeDownloadCanceled:(NSNotification*)notification
{
	SKDownload *download = notification.rm_storeDownload;
    NSString *productIdentifier = notification.rm_productIdentifier;
    SKPaymentTransaction *transaction = notification.rm_transaction;
}

- (void)storeDownloadPaused:(NSNotification*)notification
{
	SKDownload *download = notification.rm_storeDownload;
    NSString *productIdentifier = notification.rm_productIdentifier;
    SKPaymentTransaction *transaction = notification.rm_transaction;
}

###Refresh receipt notifications (iOS 7+ only)

- (void)storeRefreshReceiptFailed:(NSNotification*)notification;
{
    NSError *error = notification.rm_storeError;
}

- (void)storeRefreshReceiptFinished:(NSNotification*)notification { }

##Receipt verification

RMStore doesn't perform receipt verification by default but provides reference implementations. You can implement your own custom verification or use the reference verifiers provided by the library.

Both options are outlined below. For more info, check out the wiki.

###Reference verifiers

RMStore provides receipt verification via RMStoreAppReceiptVerifier (for iOS 7 or higher) and RMStoreTransactionReceiptVerifier (for iOS 6 or lower). To use any of them, add the corresponding files from RMStore/Optional into your project and set the verifier delegate (receiptVerifier) at startup. For example:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    const BOOL iOS7OrHigher = floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1;
    _receiptVerifier = iOS7OrHigher ? [[RMStoreAppReceiptVerifier alloc] init] : [[RMStoreTransactionReceiptVerifier alloc] init];
    [RMStore defaultStore].receiptVerifier = _receiptVerifier;
    // Your code
    return YES;
}

If security is a concern you might want to avoid using an open source verification logic, and provide your own custom verifier instead.

###Custom verifier

RMStore delegates receipt verification, enabling you to provide your own implementation using the RMStoreReceiptVerifier protocol:

- (void)verifyTransaction:(SKPaymentTransaction*)transaction
                           success:(void (^)())successBlock
                           failure:(void (^)(NSError *error))failureBlock;

Call successBlock if the receipt passes verification, and failureBlock if it doesn't. If verification could not be completed (e.g., due to connection issues), then error must be of code RMStoreErrorCodeUnableToCompleteVerification to prevent RMStore to finish the transaction.

You will also need to set the receiptVerifier delegate at startup, as indicated above.

##Downloading content

RMStore automatically downloads Apple-hosted content and provides a delegate for a self-hosted content.

###Apple-hosted content

Downloadable content hosted by Apple (SKDownload) will be automatically downloaded when purchasing o restoring a product. RMStore will notify observers of the download progress by calling storeDownloadUpdate: and finally storeDownloadFinished:. Additionally, RMStore notifies when downloads are paused, cancelled or have failed.

RMStore will notify that a transaction finished or failed only after all of its downloads have been processed. If you use blocks, they will called afterwards as well. The same applies to restoring transactions.

###Self-hosted content

RMStore delegates the downloading of self-hosted content via the optional contentDownloader delegate. You can provide your own implementation using the RMStoreContentDownloader protocol:

- (void)downloadContentForTransaction:(SKPaymentTransaction*)transaction
                              success:(void (^)())successBlock
                             progress:(void (^)(float progress))progressBlock
                              failure:(void (^)(NSError *error))failureBlock;

Call successBlock if the download is successful, failureBlock if it isn't and progressBlock to notify the download progress. RMStore will consider that a transaction has finished or failed only after the content downloader delegate has successfully or unsuccessfully downloaded its content.

##Transaction persistence

RMStore delegates transaction persistence and provides two optional reference implementations for storing transactions in the Keychain or in NSUserDefaults. You can implement your transaction, use the reference implementations provided by the library or, in the case of non-consumables and auto-renewable subscriptions, get the transactions directly from the receipt.

For more info, check out the wiki.

##Requirements

RMStore requires iOS 5.0 or above and ARC.

##Roadmap

RMStore is in initial development and its public API should not be considered stable. Future enhancements will include:

##License

Copyright 2013-2014 Robot Media SL

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Comments
  • Feature Request: In completionblock of restore, provide array of productID's

    Feature Request: In completionblock of restore, provide array of productID's

    The completion block of restoreOnSuccess does not provide and productID's of IAP's, so I have to manually add/remove the observe and implement an extra method that gets notifications when products have been purchased/restored. It would simply save some time/code if the completion block returns restored product ID's.

    enhancement easy 
    opened by BobDG 30
  • Use system frameworks instead of OpenSSL

    Use system frameworks instead of OpenSSL

    RMAppReceipt uses OpenSSL to extract the app receipt as ASN1 data from the PKCS7 container and then parse the ASN1 data into an object.

    In order to avoid external dependencies it would be better to use system frameworks instead. Sadly, my cryptography-fu is not strong enough to do it. Any takers?

    According to the this app, it appears to be possible.

    enhancement 
    opened by hpique 12
  • Build fails unless you link libssl and libcrypto libraries with the Pods-RMStore target

    Build fails unless you link libssl and libcrypto libraries with the Pods-RMStore target

    When running pod install for the first time on a project with RMStore the project will not build. You have to link the Pods-RMStore target in the Pods project with the libssl and libcrypto libraries.

    Relevant portion of build log:

    (null): "_d2i_PKCS7_fp", referenced from:
    (null): +[RMAppReceipt dataFromPCKS7Path:] in libPods.a(RMAppReceipt.o)
    (null): "_SHA1", referenced from:
    (null): -[RMAppReceipt verifyReceiptHash] in libPods.a(RMAppReceipt.o)
    (null): "_PKCS7_free", referenced from:
    (null): +[RMAppReceipt dataFromPCKS7Path:] in libPods.a(RMAppReceipt.o)
    (null): "_ASN1_get_object", referenced from:
    (null): _RMASN1ReadInteger in libPods.a(RMAppReceipt.o)
    (null): _RMASN1ReadOctectString in libPods.a(RMAppReceipt.o)
    (null): _RMASN1ReadString in libPods.a(RMAppReceipt.o)
    (null): +[RMAppReceipt enumerateASN1Attributes:length:usingBlock:] in libPods.a(RMAppReceipt.o)
    (null): Symbol(s) not found for architecture armv7s
    (null): Linker command failed with exit code 1 (use -v to see invocation)
    

    Podfile:

    platform :ios, '7.0'
    pod 'RMStore', '~> 0.4.2'
    
    invalid 
    opened by mmorey 11
  • Restore Purchase is always successful, even when product has not been purchased

    Restore Purchase is always successful, even when product has not been purchased

    I am testing on a device in iOS 7 in the sandbox. I logged out of my iTunes account and cleared the keychain data. I downloaded a fresh version of the app and used a brand new test account. I hit the Restore button for my non-consumable product. I was asked to enter my iTunes ID and password twice, even though I am positive I entered it correctly the first time. The product was then restored successfully, even though it had not yet been purchased by this test account user. I tried this with multiple test accounts and it is reproducible every time.

    question 
    opened by inPhilly 11
  • Watchdog timer for products request. Observer protocol extension & some minor fixes.

    Watchdog timer for products request. Observer protocol extension & some minor fixes.

    About watchdog timer feature.

    Watchdog will throw a timeout error in case of network lag on products request. It guarantees fixed time response to customer after his tap on Purchase button for in-app.

    I didn't include example in commit but my use case is below. In my apps after user taps "Purchase" button I show modal activity indicator view then make products request via RMStore. If I've got a products response before watchdog timer fires then there is a big probability that Apple servers will be reachable while payment transaction also. If network is bad I get timeout error from watchdog timer. Then I can choose to dismiss modal activity indicator view and place payment (with network activity indicator as in your example) or show "Try to Retry" message for customer in case of timeout error accordingly.

    P.S. Thanks for great library. Keep rocking!

    opened by IvanRublev 8
  • Verification failed with app in production.

    Verification failed with app in production.

    The app version mismatched the bundle version. By using short sting we are checking for the correct app version.

    Issue:https://github.com/robotmedia/RMStore/issues/58 Info about the change: http://stackoverflow.com/questions/6876923/difference-between-xcode-version-cfbundleshortversionstring-and-build-cfbundl

    opened by Pjata 7
  • Problem with AppReceiptVerificator with cocoapods

    Problem with AppReceiptVerificator with cocoapods

    I was using RMStore from a downloaded file, but I'v changed to pods now and it can't find RMStoreAppReceiptVerificator.h/.m. The problem is at the .podspec it states that the subspec 'AppReceiptVerificator' be available only for iOS 7.0, but my app deployment target is 5.0. What should I do? Change my pod file to 7.0 only for RMStore? Or what? I have configured RMStore just like the demo Proyect with this line:

    _receiptVerificator = iOS7OrHigher ? [[RMStoreAppReceiptVerificator alloc] init] : [[RMStoreTransactionReceiptVerificator alloc] init]; [RMStore defaultStore].receiptVerificator = _receiptVerificator;

    Thanks

    question 
    opened by 942v 7
  • How to get the receipt after

    How to get the receipt after "receipt validation locally"

    In my applications I am using RMStore library. After calling addPayment:success:failure method of RMStore class, I am doing receipt validation locally. But after validation where I will get the transaction receipt. Sample receipt after verification is below.

    { environment = Sandbox; receipt = { "adam_id" = 0; "application_version" = "1.6"; "bundle_id" = "Some bundle id"; "download_id" = 0; "in_app" = ( { "is_trial_period" = false; "original_purchase_date" = "2013-10-10 06:43:45 Etc/GMT"; "original_purchase_date_ms" = 1381387425000; "original_purchase_date_pst" = "2013-10-09 23:43:45 America/Los_Angeles"; "original_transaction_id" = 1000000089656289; "product_id" = "product_id"; "purchase_date" = "2013-12-03 08:24:49 Etc/GMT"; "purchase_date_ms" = 1386059089000; "purchase_date_pst" = "2013-12-03 00:24:49 America/Los_Angeles"; quantity = 1; "transaction_id" = 1000000089656289; }, { "is_trial_period" = false; "original_purchase_date" = "2013-12-03 08:24:49 Etc/GMT"; "original_purchase_date_ms" = 1386059089000; "original_purchase_date_pst" = "2013-12-03 00:24:49 America/Los_Angeles"; "original_transaction_id" = 1000000095357076; "product_id" = "product_id"; "purchase_date" = "2013-12-03 08:24:49 Etc/GMT"; "purchase_date_ms" = 1386059089000; "purchase_date_pst" = "2013-12-03 00:24:49 America/Los_Angeles"; quantity = 1; "transaction_id" = 1000000095357076; } ); "receipt_type" = ProductionSandbox; "request_date" = "2013-12-03 08:24:56 Etc/GMT"; "request_date_ms" = 1386059096603; "request_date_pst" = "2013-12-03 00:24:56 America/Los_Angeles"; }; status = 0; }

    question 
    opened by arunkumariitkgp 7
  • Question about 0.5 and offline verification

    Question about 0.5 and offline verification

    Hello,

    I used the RMStoreAppReceiptVerificator's method verifyAppReceipt:to verify my receipt offline and then the RMAppReceipt's containsInAppPurchaseOfProductIdentifier: method to find out if a user has bought a specific product. That worked very well!

    Today I just updated to 0.5 and found out that some things have changed.... So I am wondering if I need to adopt my code?

    In the Wiki (https://github.com/robotmedia/RMStore/wiki/Receipt-verification) it says that I need to add the 'Apple Inc. Root Certificate' to my project?!? Is this new since 0.5? Do I really have to add it?

    And is there anything else I need to be aware?

    Thanks, Georg

    question 
    opened by georgbachmann 6
  • Restoring Transactions are never persisted

    Restoring Transactions are never persisted

    When I successfully restore a transactions with the following code:

     [[RMStore defaultStore] restoreTransactionsOnSuccess:^{
            // success handler
        } failure:^(NSError *error) {
            // failure handler
        }
     ]
    

    And later call the following code to verify that the purchase restoration has been completed:

    RMStore *store =[RMStore defaultStore];
    RMStoreKeychainPersistence *transactionStore = store.transactionPersistor;
    
    return [transactionStore isPurchasedProductOfIdentifier:@"myProductId"];
    

    I get a result of "false" when I expect it to be "true" after restoring my purchase.

    When I look at the RMStore.m code, it looks like there is no call to persist the transaction during the restore process.

    Note: I am using RMStoreKeychainPersistence method to persist my IAP transactions.

    invalid 
    opened by linusthe3rd 6
  • Downloadable content support

    Downloadable content support

    Notes:

    • Commit 0246df1 is a hack to fix an issue with restored transactions. Non-consumable products with downloadable content are some times restored twice. This happens (in the sandbox environment at least) the second time you call restoreCompletedTransactions or calling restoreCompletedTransactions after buying a different product first.
    • The RMStore log "RMStore: restore transactions finished" in the case of downloadable content, shows much earlier than the storeRestoreTransactionsFinished: notification call, because the notification is posted once all the downloads are finished. I don't consider it a big issue but I just want to point it out.

    This branch would break tests. If you approve the merge I would work on tests and documentation before you do the actual merge.

    opened by xavigil 6
  • Subscriptions

    Subscriptions

    Hey!

    We've seen that there haven't been any updates for quite some time. Does it still work on iOS 13? Does it support subscriptions still on the latest iOS?

    We'd love to use RMStore as it has worked out perfectly for us in the past.

    opened by ForestRingGames 3
  • Checking for an active auto-renewable subscription returns incorrect results

    Checking for an active auto-renewable subscription returns incorrect results

    There's a very nasty logical flaw in RMAppReceipt's -containsActiveAutoRenewableSubscriptionOfProductIdentifier:forDate: method.

    This method first sorts through the receipt records looking for the newest one (using the expiration date) and then only checks that single record against the given date. One major problem with this is that the real-life production App Store receipts sometimes have renewal records from the future in them. This means if you use the current date (or a date from a few hours ago, or yesterday, or whatever) as your reference date, this method will first find the newest possible record - which is sometimes one that has already been generated for the NEXT billing period. It will then check if the date comes after that record's start date - which of course it does not. It then erroneously returns NO.

    I posted a long thread on twitter about my adventures tracking this down here: https://twitter.com/BigZaphod/status/1162094913552625665

    opened by BigZaphod 2
  • TestFlight vs Sandbox for RMAppReceipt

    TestFlight vs Sandbox for RMAppReceipt

    In development (XCode 10, iOS12), I'm able to use RMAppReceipt to verify autorenewing subscriptions just fine, using:

    RMAppReceipt *appReceipt = [RMAppReceipt bundleReceipt];  
        if (appReceipt) {
            isActive =  [appReceipt containsActiveAutoRenewableSubscriptionOfProductIdentifier:@"0001" 
            forDate:[NSDate date]];
        }
        if (isActive) {
            NSLog(@"PatronSignupViewController: Got a list of subscriptions, a subscription IS active! Restored!");
        } else { //if receipt does not contain an active subscription
            NSLog(@"PatronSignupViewController: Got a list of purchases, but Subscription NOT active!");
    

    However, when I use TestFlight to beta test the app, the system can never find the autorenewing subscription (after I've purchased it in TestFlight - purchasing in TestFlight works fine in TestFlight too).

    Is there something fundamentally different that I should be aware of when it comes to purchases, products, RMStore, and TestFlight and Sandbox behaviors? Thx

    opened by dflateau 0
Releases(v0.7.0)
  • v0.7.0(Dec 3, 2014)

    Restore operations and the corresponding observer notification now include the array of restored transactions. Includes incompatible API changes.

    RMStore

    • #53: Restore operations and the corresponding observer notification now include the array of restored transaction. Great job @karolus!

    RMStoreUserDefaultsPersistence

    • #122: Subclasses can use a different NSUserDefaults by overriding. Thanks @ChaosCoder!
    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Sep 23, 2014)

    Adds support for deferred transactions introduced in iOS 8. Includes incompatible API changes.

    RMStore

    • #72: Add rm_ prefix to NSNotification category methods. This is an incompatible API change. If you are using these notifications you will have to change your code. Thanks @gnatok!
    • #109: Add support for deferred transactions introduced in iOS 8.

    Other

    • #92: Migrated from OCUnit to XCTest. Thanks @gnatok!
    • #104: Use RMStore table for localized strings. Thanks @mckaskle!
    Source code(tar.gz)
    Source code(zip)
  • v0.5.2(Aug 10, 2014)

    Minor fixes for iOS 8 and code improvements.

    RMStore

    • Log only when DEBUG is true (b59e1148760de8cf47f0be285b6924b8ec568d85). Thanks @streeter!

    RMAppReceipt

    • Rename hash to receiptHash to avoid name collisions in iOS 8 (c6d1c5770d7e6a261b7891eecc049225df26bb96). Thanks @kommen!
    Source code(tar.gz)
    Source code(zip)
  • v0.5.1(Jun 25, 2014)

    Minor warning fixes and code improvements, plus fixes for Objective-C++ compilation.

    RMStore

    • Fix unused variable warning when building for Release (5bebfa54272310d9b17bdc2e4cd44e461efe2560).

    RMAppReceipt

    • Fixes #78: Objective-C++ compilation. Thanks @jcaille!

    Other

    • #70: The podspec now uses the OpenSSL pod as a dependency.
    Source code(tar.gz)
    Source code(zip)
  • v0.5(May 16, 2014)

  • v0.4.3(May 16, 2014)

    Minor bug fixes and improvements to code and receipt verification.

    RMStoreAppReceiptVerificator

    • Implements #18: Verify receipt signature with Apple Root certificate. To use you must include AppleIncRootCertificate.cer in your app bundle as indicated in the wiki.
    • Fixes #57: Fixed bug that returned null receipt dates in certain cases by explicitly setting the NSDateFormatter locale to "en_US_POSIX". This was a bug due to an Apple bug/feature related to the 24-hour time setting.

    RMStoreKeychainPersistence

    • Fixes #44: Fix 64-bit casting warnings.

    RMStoreTransactionReceiptVerificator

    • Fixes #44: Fix 64-bit casting warnings.
    Source code(tar.gz)
    Source code(zip)
  • v0.4.2(Nov 18, 2013)

    Minor bug fixes and code improvements.

    RMStore

    • Fixes #31: Introduce RMStoreErrorCodeUnableToCompleteVerification to enable verficators to communicate inability to complete verification (most likely due to network issues).
    • Fixes bug causing early restore transaction finished notifications in subsequent restore transactions calls (c198cc9d95de8b7e371f6ccbfbe151c8764caa98).

    RMStoreKeychainPersistence

    • Fixes #34: Use return value to check for success instead of indirect error.

    RMStoreTransactionReceiptVerificator

    • Fixes #34: Use return value to check for success instead of indirect error.

    RMStoreAppReceiptVerificator

    • Use RMStoreErrorDomain instead of RMErroDomainStoreAppReceiptVerificator (3ea639abc9e43d996bb1ce09f8c52bca715c621d).
    Source code(tar.gz)
    Source code(zip)
  • v0.4.1(Oct 28, 2013)

    RMStore

    • Fixes bug preventing product request notifications from being received (c198cc9d95de8b7e371f6ccbfbe151c8764caa98).

    RMStoreKeychainPersistence

    • Fixes #28: compilation warnings due to NSCAssert when building for release.
    • Improve performance by caching keychain transactions (0705b4f8d4e6313417ba02ab53e8a2c6c25b4048).
    • Return an empty transactions dictionary if JSON parsing fails (0705b4f8d4e6313417ba02ab53e8a2c6c25b4048).
    • Log errors instead of using assertions (2f824467168a3041690e575585f0879694452377, 4fc050c28cb4b3d0cf22213b6df8f2b2a20d2620).

    Other

    • Fixes #22: add OpenSSL to the podspec (bb658566fcabcf0ad44ca61b1ec2a49f245b66c0).
    Source code(tar.gz)
    Source code(zip)
Owner
Robot Media
Robot Media
In-app purchases and subscriptions made easy. Support for iOS, iPadOS, watchOS, and Mac.

In-app purchases and subscriptions made easy. Support for iOS, iPadOS, watchOS, and Mac.

RevenueCat 1.6k Jan 6, 2023
A modern In-App Purchases management framework for iOS.

MerchantKit A modern In-App Purchases management framework for iOS developers. MerchantKit dramatically simplifies the work indie developers have to d

Benjamin Mayo 1.1k Dec 17, 2022
Handle in-app purchases in iOS in a convenient way

InAppPurchases Handle in-app purchases in iOS in a convenient way. Overview InAppPurchases covers all the basic aspects of in-app purchases in swift i

Umar Awais 4 Nov 8, 2022
TPInAppReceipt is a lightweight, pure-Swift library for reading and validating Apple In App Purchase Receipt locally.

TPInAppReceipt is a lightweight, pure-Swift library for reading and validating Apple In App Purchase Receipt locally. Features Read all

Pavel T 520 Jan 4, 2023
Easy to use iOS library with components for input of Credit Card data.

AnimatedCardInput This library allows you to drop into your project two easily customisable, animated components that will make input of Credit Card i

Netguru 39 Oct 16, 2022
Better payment user experience library with cool animation in Swift

?? Preview ?? Features Easily usable Simple Swift syntax Cool flip animation Compatible with Carthage Compatible with CocoaPods Customizable Universal

yassir RAMDANI 177 Nov 20, 2022
Easily integrate Credit Card payments module in iOS App. Swift 4.0

MFCard Buy me a coffee MFCard is an awesome looking Credit Card input & validation control. Written in Swift 3. YOoo, Now MFCard is on Swift 5. Swift

MobileFirst 362 Nov 29, 2022
Make and accept payments in your iOS app via Venmo

Venmo iOS SDK The Venmo iOS SDK lets you make and accept payments in your app using Venmo. Installation If you're using CocoaPods: If you don't have a

Venmo 170 Dec 26, 2022
In App Purchase Manager framework for iOS

InAppFramework In App Purchase Manager framework for iOS Disclaimer I know it's been too long since the last update, quite a few things happened in my

Sándor Gyulai 40 May 23, 2020
Accept credit cards and PayPal in your iOS app

Important: PayPal Mobile SDKs are Deprecated. The APIs powering them will remain operational long enough for merchants to migrate, but the SDKs themse

PayPal 973 Dec 18, 2022
Square In-App Payments iOS SDK SwiftUI

Square In-App Payments iOS SDK SwiftUI Build remarkable payments experiences in

Ashley Bailey 2 Mar 8, 2022
SwiftUI BusinessCard - Created iOS Business card app to practice SwiftUI

SwiftUI_BusinessCard Created iOS Business card app to practice SwiftUI

null 0 Jan 29, 2022
iOS SDK for cross-platform in-app purchase and subscription infrastructure, revenue analytics, engagement automation, and integrations

Qonversion is the data platform to power in-app subscription revenue growth. fast in-app subscriptions implementation back-end infrastructure to valid

Qonversion 253 Dec 18, 2022
A jailed in-app purchase cracker for iOS 12.2-15.6

Satella Jailed For, um, educational purposes only or something. Definitely don't use this to pirate in-app purchases in apps to which you don't have l

Lilly 314 Dec 31, 2022
Ruby Gem for Rails - Easy iTunes In-App Purchase Receipt validation, including auto-renewable subscriptions

Monza is a ruby gem that makes In-App Purchase receipt and Auto-Renewable subscription validation easy. You should always validate receipts on the ser

Gabriel 159 Jan 7, 2023
With SwiftUI payment share app

Splitpayment With SwiftUI payment share app.

Ahmet Onur Şahin 3 Apr 18, 2022
OnTime - OnTime App is for Scheduling your day and prioritizing your task and also for saving notes

OnTime OnTime App is for Scheduling your day and prioritizing your task and also

Mohammed Sulaiman 1 Jan 7, 2023
Implement donate to Ukraine inside your app, with Apple Pay

DonateToUkraine gives you a simple way to provide "donate to Ukraine" functionality in your app via an official donation service (endorsed here). The service will be opened inside the app, keeping a native feel. Apple Pay is supported.

Oleg Dreyman 22 Aug 2, 2022
Ios-card-transition - iOS CocoaPod to create beautiful card transitions

CSCardTransition CSCardTransition is a small library allowing you to create wond

Creastel 12 Oct 31, 2022