Giter Club home page Giter Club logo

kvitto's Introduction

Kvitto

"Kvitto, it means Receipt in Swedish. The trend of using Swedish words for libraries is pretty big" -- Hugo Tunius via Twitter

Allows parsing an validation of iTunes App Store receipts. Receipts also contain the In App Purchase receipts. For auto-renewable subscriptions the subscription expiration date is available.

Documentation

Look at the included Demo app's ViewController to see how to load and validate a Store receipt locally. This sample is in Objective-C to demonstrate the Kvitto - although written in Swift - can also be used from Objective-C code.

There is also a pure Swift Demo function.

License

It is open source and covered by a standard 2-clause BSD license. That means you have to mention Cocoanetics as the original author of this code and reproduce the LICENSE text inside your app.

You can purchase a Non-Attribution-License for 75 Euros for not having to include the LICENSE text.

We also accept sponsorship for specific enhancements which you might need. Please contact us via email for inquiries.

kvitto's People

Contributors

flymg avatar keeshux avatar odrobnik avatar otaran avatar samsonjs avatar stellakovalchuk avatar thaya-cameraxis avatar theome avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kvitto's Issues

Podspec push warnings/notes

I ignored these warnings publishing 1.0.5:

    - NOTE  | [Kvitto/Core] xcodebuild:  note: Using new build system
    - NOTE  | [Kvitto/Core] xcodebuild:  note: Building targets in parallel
    - NOTE  | [Kvitto/Core] xcodebuild:  note: Using codesigning identity override: -
    - NOTE  | [Kvitto/Core] xcodebuild:  note: Planning build
    - NOTE  | [Kvitto/Core] xcodebuild:  note: Constructing build description
    - NOTE  | [Kvitto/Core] xcodebuild:  warning: Skipping code signing because the target does not have an Info.plist file and one is not being generated automatically. (in target 'App' from project 'App')
    - NOTE  | [Kvitto/Core] xcodebuild:  warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.1.99. (in target 'DTFoundation' from project 'Pods')

I need to find out how to generate HTML documentation and how to build that on my Mac mini Server...

The message about deployment target being less than 9 is odd, as the spec has the iOS deployment target set to 9.

Will Local receipt validation require AppStore authentication?

Hi - I'm interested in using your library for local receipt validation before sending it up to my API. I was wondering though. During the receipt validation flow, will the dreaded IAP authentication modals pop up? I have a requirement to not show those to the user.

Check for actualSequence.count == 5 may fail as Apple doesn't always supply 5 elements.

Thank you for the great library!

Wanted to give you a heads up on the following line of code:

let actualSequence = containedSequence[0] as? [AnyObject] , actualSequence.count == 5,

At some point this year Apple started to supply 3 items in this sequence. I changed it to actualSequence.count > 2 as there is no need to use anything from it above [2]. Since then it is working alright.

This was the issue both in production receipts and sandbox in August 2020. I'm not sure if this issue still persists. But the above change will relax the requirement on the sequence to the data you really need, not stricter.

Thank you again! Looks like Apple is fiddling around with the receipt lately, hope this input will help you and others.

Question regarding Apple's upcoming migration to SHA-256 signing certificates

Apple will soon start to use the SHA-256 certificates to sign the app receipts. What I would like to ask is will that change create problems for Kvitto's users assuming they don't do local receipt validation and rely on Receipt(contentsOfURL: ...) API?
I've done a bit of testing with iOS 16.6 beta 5 and Xcode 14.3.1 and didn't experience any problems.
Please let me know if you need an example of a new receipt.
More info about the upcoming change can be found at https://developer.apple.com/documentation/technotes/tn3138-handling-app-store-receipt-signing-certificate-changes

Support of StoreKitTest receipts

In Xcode 12 Apple added a new way of testing In-App purchases (see Introducing StoreKit Testing in Xcode WWDC 2020 talk for more info). The new method relies on receipts signed with a different private key than ordinary receipts. During an attempt to parse such a receipt I get an "Indefinite Length form encounted, not implemented" error inside DTASN1Parser.
Can you please add the support of StoreKitTest receipts in Kvitto? I can send you an example of such a receipt over an email if you need one. This functionality was implemented in TPInAppReceipt, so you can check it for reference.

ld: framework not found DTFoundation for architecture ...

Using Carthage to build Kvitto, in Cartfile:
github "Cocoanetics/Kvitto" "develop"

When build with my iPhone or Generic iOS Device, got the error:
ld: framework not found DTFoundation for architecture arm64
sometimes its:
ld: framework not found DTFoundation for architecture armv7

When build with Simulators, got the error:
ld: framework not found DTFoundation for architecture x86_64

However, the project in Carthage/Checkouts/Kvitto always build success.
I found a related issue in DTFoundation Cocoanetics/DTFoundation#109
It looks like something wrong with the project setting for Carthage usage.

Unit tests are failing with DTFoundation version 1.7.18

Hey,

We recently updated swift packages in our app and with the updates came DTFoundation 1.7.18. In our tests, receipt parsing stopped working in our app with combination of Kvitto (version 1.0.6) and DTFoundation (version 1.7.18). On older version 1.7.17 receipts are parsed successfully and unit tests are all green as well.

Error in parseData?

Hey Oliver,

Kvitto looks cool. :-) So I wanted to use it and included it as a CocoaPod. In Dev mode, I parse a receipt, but on line 126 in Receipt.swift I get an error:

guard let rootArray = DTASN1Serialization.objectWithData(data) as? [[AnyObject]]

According to lldb:

po DTASN1Serialization.objectWithData(data).dynamicType
   Swift.Optional<Swift.AnyObject>

If I rewrite this a bit:

let _rootArray = DTASN1Serialization.objectWithData(data)
guard let rootArray = _rootArray as? [[AnyObject]]

I get to know that _rootArray is an NSArray? with a count of 2 where [0] is an NSString and [1] is an Array. The String [0] in my case was "1.2.840.113549.1.7.2", not sure what this is. The NSArray [1] has a count of 1, another NSArray, with 5 elements. I dove into it further but wasn't sure what to make out of it. I've attached the po of _rootArray: https://www.dropbox.com/s/moalpyplpbtcfnk/receipt.txt?dl=0

Do you have any pointers to what I should do?

Cheers

Nik

Receipt parsing fails due to format changes

Since a few days ago, some of the App Receipts that are generated by iOS have a slightly different format and Kvitto fails to parse these receipts properly. In my app, around 50% of the app receipts are affected. I'm already using Kvitto in my app since about a year, but this problem occurred for the first time on September 24.

It seems that the issue is that sometimes the date format contains fractional seconds, so for example a date looks like this

2020-09-27T12:07:19.686Z

instead of this:

2020-09-27T12:07:19Z

The method _dateFromRFC3339String() fails to parse the former date string, so _dateFromData() throws and Receipt.init?(contentsOfURL) returns nil.

It's possible that there are some more changes to the format - I'm still investigating. If I find time in the next days, I'll prepare a pull request with a fix.

How to Determine Eligibility?

Hi,

i try to determine eligibility for an introductory offer. Apple's docs say:

In the receipt, check the values of the is_trial_period and the is_in_intro_offer_period for all in-app purchase transactions. If either of these fields are true for a given subscription, the user is not eligible for an introductory offer

I did not find a way to read the is_trial_period or the is_in_intro_offer_period values from DTInAppPurchaseReceipt? Is there a way to access them?

Kind regards,
Markus

DateFormatter may cause performance problems and should be reused

This blog post by Sarun has made me aware of the poor performance of DateFormatter if it isn't reused. If these estimations are correct, each call to _dateFromRFC3339String in Functions.swift can take more than 100ms (initialization of a date formatter plus updating its locale and time zone).

As an App Store receipt can easily contain dozens of dates, and Kvitto might be used on the main thread (as in the example project), there's a real risk that this performance issue can lead to watchdog terminations.

Initialization and configuration of the DateFormatter should be done only once.

Carthage build failed with Xcode 8.1

Build with Xcode 8.1, Swift 3.1, failed with:
'error: 'objc_unretainedPointer' is unavailable: use a __bridge cast instead'

Maybe related to Cocoanetics/DTFoundation#107

Here is the full output:

*** Building scheme "Kvitto" in Kvitto.xcodeproj
** CLEAN FAILED **

The following build commands failed:
Check dependencies
(1 failure)
** BUILD FAILED **

The following build commands failed:
CompileC ../Library/Developer/Xcode/DerivedData/Kvitto-fwlzvoaknmfsvueudpxmjrwsyrzz/Build/Intermediates/DTFoundation.build/Release-iphoneos/DTFoundation\ (iOS).build/Objects-normal/armv7/NSObject+DTRuntime.o Core/Source/Runtime/NSObject+DTRuntime.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)
../Carthage/Checkouts/Kvitto/Externals/DTFoundation/Core/Source/Runtime/NSObject+DTRuntime.m:51:38: error: 'objc_unretainedPointer' is unavailable: use a __bridge cast instead
A shell task (/usr/bin/xcrun xcodebuild -project ../Carthage/Checkouts/Kvitto/Kvitto.xcodeproj -scheme Kvitto -configuration Release -sdk iphoneos ONLY_ACTIVE_ARCH=NO BITCODE_GENERATION_MODE=bitcode CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= CARTHAGE=YES clean build) failed with exit code 65:
** CLEAN FAILED **

The following build commands failed:
Check dependencies
(1 failure)
** BUILD FAILED **

The following build commands failed:
CompileC ../Developer/Xcode/DerivedData/Kvitto-fwlzvoaknmfsvueudpxmjrwsyrzz/Build/Intermediates/DTFoundation.build/Release-iphoneos/DTFoundation\ (iOS).build/Objects-normal/armv7/NSObject+DTRuntime.o Core/Source/Runtime/NSObject+DTRuntime.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)

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.