Giter Club home page Giter Club logo

Comments (8)

bizz84 avatar bizz84 commented on May 17, 2024

I am not very familiar myself with receipt validation and I won't be able to help on this one unfortunately. @phimage may have a bit more insight as he implemented the feature in this project.

from swiftystorekit.

phimage avatar phimage commented on May 17, 2024

Sorry, I don't know what @fbartolom talk about (need better explanation...)

all information about receipt validation
https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Introduction.html#//apple_ref/doc/uid/TP40010573-CH105-SW1

from swiftystorekit.

fbartolom avatar fbartolom commented on May 17, 2024

In fact I know that post you are referring to. But as you may also see, it just speaks of validating the purchase locally or on the AppStore, yet always from the app. In my case I need to validate the certificate from the backoffice in order to update a DB field in the case the purchase is correct. Unfortunately I found no solution for sending the receipt created by the appStoreReceiptURL to the backoffice in order for it to submit it to the Appstore for its due confirmation.

from swiftystorekit.

ShawnAukstak avatar ShawnAukstak commented on May 17, 2024

@fbartolom I was able to accomplish this by doing something similar to the below. Essentially once the SwiftyStoreKit.purchaseProduct completes with a 'Success' result, the receipt data should be stored in NSBundle.mainBundle().appStoreReceiptURL. You can then send this to along to your server for validation.

  private func processPaymentRequest() {
    SwiftyStoreKit.purchaseProduct(skProduct.productIdentifier) { result in
      switch result {
      case .Success(let productId):
        print("Purchase Success: \(productId)")
        self.verifyInAppPurchase() { result in
          //TODO - verify completion handler.
        }
      case .Error(let error):
        //TODO - Handle error
      }
    }
  }

  private func verifyInAppPurchase(completionHandler: ([String:String]?) -> Void) {
    if let dataString = InAppReceipt.base64EncodedString {
       //TODO - 
       //This is where you put your network request to server, sending the dataString receipt data.
    }
  }

  internal class InAppReceipt {
    static var URL: NSURL? {
      return NSBundle.mainBundle().appStoreReceiptURL
    }

    static var data: NSData? {
      if let receiptDataURL = URL, data = NSData(contentsOfURL: receiptDataURL) {
        return data
      }
      return nil
    }

    // The base64 encoded receipt data.
    static var base64EncodedString: String? {
      return data?.base64EncodedStringWithOptions([])
    }
  }

from swiftystorekit.

OleksiiKolosovskyi avatar OleksiiKolosovskyi commented on May 17, 2024

What about situation, when backend not responding? We need call paymentQueue.finishTransaction manually, when backend respond succeed. How do this with SwiftyStoreKit?

from swiftystorekit.

paulw11 avatar paulw11 commented on May 17, 2024

Further to @AlekseyKolosovskiy comment, SwifyStoreKit's approach to purchasing doesn't comply with best practice; it calls finishTransaction before advising the app of the purchase via the completion closure. finishTransaction should not be called until the app has persisted the purchase. It should be the responsibility of the caller to make a call to finishTransaction, perhaps via a function on SwiftyStoreKit rather than SwiftyStoreKit doing it before the callback

from swiftystorekit.

skymook avatar skymook commented on May 17, 2024

Swift 2.2
I feel my problem relates to what @paulw11 says. It seems the call back is fired almost right away.

I'm having this problem with an auto renewing subscription. When a purchase is a success, it calls verify receipt, and at this point I can check with a remote server who checks the receipt with Apple's servers.

First I call purchaseProduct. On success I call verifyReceipt, but the call back that calls verifyReceipt is fired before the purchase is complete, and then doesn't fire sometimes when the user completes the purchase with Apple.

I have found it intermittent. Sometimes firing a second time on purchase completion, and sometimes not.

// purchase button
@IBAction func purchaseButton(sender: AnyObject) {
    SwiftyStoreKit.purchaseProduct(api.productID) { result in

        switch result {
        case .Success(let productId):
            // verify purchase in app first
            self.verifyPurchase()
        case .Error(let error):
            print("Purchase Failed: \(error)")
            switch error {
            case .Failed(let error):
                if error.domain == SKErrorDomain {
                    self.alertMessageWithTitle("Purchase failed", message: "Please check your Internet connection or try again later")
                } else {
                    self.alertMessageWithTitle("Purchase failed", message: "Unknown error. Please contact support")
                }
            case .InvalidProductId(let productId):
                self.alertMessageWithTitle("Purchase failed", message: "\(productId) is not a valid product identifier")
            case .NoProductIdentifier:
                self.alertMessageWithTitle("Purchase failed", message: "Product not found")
            case .PaymentNotAllowed:
                self.alertMessageWithTitle("Payments not enabled", message: "Please enable payments to make this purchase")
            }
        }
    }
}

func verifyPurchase() {
    SwiftyStoreKit.verifyReceipt(password: "<secret key>") { result in
        switch result {
        case .Success(let receipt):
            // verify the subscription in app first
            let purchaseResult = SwiftyStoreKit.verifySubscription(
                productId: api.productID,
                inReceipt: receipt,
                validUntil: NSDate()
            )

            switch purchaseResult {
            case .Purchased(let expiresDate):
                // this fires when user completes (sometimes)
                // product is valid, so verify with server
                // call to API here where I send the receipt
            case .Expired(let expiresDate):
                // this fires almost immediately before user completes purchase (old receipt is in place)
                print("Purchased - Product is expired since \(expiresDate)")
            case .NotPurchased:
                // handle this
            }

        // error
        case .Error(let error):
            // handle error
        }
    }
}

from swiftystorekit.

bizz84 avatar bizz84 commented on May 17, 2024

Since this issue was originally opened I have added non-atomic transactions to SwiftyStoreKit, and local receipt verification is being tracked here: #101.

I'm going to close this issue for now. I would advise everyone to update to the latest version, and open new issues if you experience any problems.

from swiftystorekit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.