Skip to content

Instantly share code, notes, and snippets.

View ren6's full-sized avatar

Renat Kurbanov ren6

View GitHub Profile
{
"latest_receipt": "long_base64_receipt_here...",
"latest_receipt_info": {
"original_purchase_date_pst": "2020-04-01 01:12:42 America/Los_Angeles",
"quantity": "1",
"subscription_group_identifier": "20537620",
"unique_vendor_identifier": "A779C77C-571E-477D-B184-474DBD2F3F5C",
"original_purchase_date_ms": "1585728762000",
"expires_date_formatted": "2020-04-01 08:17:41 Etc/GMT",
"is_in_intro_offer_period": "true",
@ren6
ren6 / app_store_receipt_example.json
Created October 15, 2019 12:57
Example of App Store receipt with 2 auto-renewable transactions (trial and renewal)
{
"status": 0,
"environment": "Sandbox",
"receipt": {
"receipt_type": "ProductionSandbox",
"adam_id": 0,
"app_item_id": 0,
"bundle_id": "com.apphud.subscriptionstest",
"application_version": "1",
"download_id": 0,
@ren6
ren6 / eligibility.swift
Last active December 16, 2020 23:32
Determining eligibility for introductory offer
func isEligibleForIntroductory(callback: @escaping (Bool) -> Void){
guard let receiptUrl = Bundle.main.appStoreReceiptURL else {
callback(true)
return
}
#if DEBUG
let urlString = "https://sandbox.itunes.apple.com/verifyReceipt"
#else
@ren6
ren6 / IAPManager.swift
Created June 18, 2019 10:36
This is a class that handles process of purchasing, validating subscriptions, refreshing receipt, restoring transactions.
//
// IAPManager.swift
// http://apphud.com
//
// Created by Apphud on 04/01/2019.
// Copyright © 2019 Apphud. All rights reserved.
//
import UIKit
import StoreKit
func expirationDateFor(_ identifier : String) -> Date?{
return UserDefaults.standard.object(forKey: identifier) as? Date
}
let subscriptionDate = IAPManager.shared.expirationDateFor("YOUR_PRODUCT_ID") ?? Date()
let isActive = subscriptionDate > Date()
func purchaseProduct(product : SKProduct, success: @escaping SuccessBlock, failure: @escaping FailureBlock){
guard SKPaymentQueue.canMakePayments() else {
return
}
guard SKPaymentQueue.default().transactions.last?.transactionState != .purchasing else {
return
}
self.successBlock = success
self.failureBlock = failure
// Starts products loading and sets transaction observer delegate
@objc func startWith(arrayOfIds : Set<String>!, sharedSecret : String){
SKPaymentQueue.default().add(self)
self.sharedSecret = sharedSecret
self.productIds = arrayOfIds
loadProducts()
}
private func loadProducts(){
let request = SKProductsRequest.init(productIdentifiers: productIds)
@ren6
ren6 / Example.swift
Created June 17, 2019 14:31
Parse Apple receipt example
private func parseReceipt(_ json : Dictionary<String, Any>) {
// It's the most simple way to get latest expiration date. Consider this code as for learning purposes. Do not use current code in production apps.
guard let receipts_array = json["latest_receipt_info"] as? [Dictionary<String, Any>] else {
self.refreshSubscriptionFailureBlock?(nil)
self.cleanUpRefeshReceiptBlocks()
return
}
for receipt in receipts_array {
let productID = receipt["product_id"] as! String
let formatter = DateFormatter()
@ren6
ren6 / Example.swift
Last active September 17, 2023 09:37
Refresh receipt example
private func refreshReceipt(){
let request = SKReceiptRefreshRequest(receiptProperties: nil)
request.delegate = self
request.start()
}
func requestDidFinish(_ request: SKRequest) {
// call refresh subscriptions method again with same blocks
if request is SKReceiptRefreshRequest {
refreshSubscriptionsStatus(callback: self.successBlock ?? {}, failure: self.failureBlock ?? {_ in})
func refreshSubscriptionsStatus(callback : @escaping SuccessBlock, failure : @escaping FailureBlock){
// save blocks for further use
self.refreshSubscriptionSuccessBlock = callback
self.refreshSubscriptionFailureBlock = failure
guard let receiptUrl = Bundle.main.appStoreReceiptURL else {
refreshReceipt()
// do not call block yet
return
}
#if DEBUG