Josh Holtz
fc2138249a
[Paywalls V2] Implement V2 variables and functions ( #4633 )
...
* This mostly works
* This mostly works
* Better tests and logic
* More tests
* Fixed onemore
* lint
* Fix tests
* Actually use this
* Fix for all quantity translation things
* More minor fixes
* Fix tests
2025-01-08 09:17:34 -06:00
Will Taylor
6a363db8df
make PurchaseParams & Win-Back APIs public
2024-11-19 13:18:21 -06:00
Will Taylor
d23fa7fae2
support redeeming winbacks offer with developer-built paywalls
2024-11-13 11:48:53 -06:00
Will Taylor
6de169a23e
support fetching eligible win-back offers for a product
2024-11-06 15:46:04 -06:00
Toni Rico
e73f10244d
Round price per period calculations to nearest 2-decimal ( #4275 )
...
* Round price per period calculations to nearest 2-decimal
* Fix tests
* Update snapshots commit
2024-09-17 10:31:02 +02:00
dd0ee262ea
[Customer Center] Initial implementation ( #3967 )
...
Alpha of the Customer Center. In this branch, it's been disabled behind
a compilation flag.
---------
Co-authored-by: Will Taylor <wtaylor151@gmail.com >
Co-authored-by: James Borthwick <109382862+jamesrb1@users.noreply.github.com >
Co-authored-by: RevenueCat Git Bot <72824662+RCGitBot@users.noreply.github.com >
Co-authored-by: JayShortway <29483617+JayShortway@users.noreply.github.com >
Co-authored-by: Toni Rico <toni.rico.diez@revenuecat.com >
Co-authored-by: Toni Rico <antonio.rico.diez@revenuecat.com >
Co-authored-by: Cody Kerns <44073103+codykerns@users.noreply.github.com >
Co-authored-by: Andy Boedo <andresboedo@gmail.com >
2024-08-09 15:26:55 +02:00
NachoSoto
2bcd0ce328
5.0.0 changes: support SK2 by default
2024-07-01 14:37:21 -05:00
Josh Holtz
c6e185ff07
Only install swiftlint on Xcode 15 jobs ( #3913 )
...
### Motivation
Better implementation of
https://github.com/RevenueCat/purchases-ios/pull/3909 and what was just
commited to `5.0-dev`
### Description
- Only install `swiftlint` on Xcode 15.3 jobs
- Also moved Ruby 3.2.2 install into `install-bundle-dependencies` which
was also done in `5.0-dev`
2024-05-18 08:21:02 -05:00
Andy Boedo and NachoSoto
4cc7d51f70
StoreProduct: add localized price per period strings (#3546 )
...
Added `localizedPricePerWeek`, `localizedPricePerMonth` and
`localizedPricePerYear`.
I started on this before noticing that we already [have an equivalent at
the package
level](https://github.com/RevenueCat/purchases-ios/blob/main/RevenueCatUI/Helpers/Package%2BVariableDataProvider.swift#L107 ),
still need to unify them.
---------
Co-authored-by: NachoSoto <ignaciosoto90@gmail.com >
2024-01-16 16:00:15 -08:00
32c63cdb46
[SK2] Add support for StoreKit Config files in SK2 ( #3365 )
...
When using StoreKit Config file, we do not have access to the
transaction history or subscription status server-side.
To work around this, we introduce a new `StoreKit2Receipt` type that
closely resembles the structure of an SK1 receipt and contains all the
transaction history and subscription status for the customer. It can be
sent in a single request to `/receipt`
---------
Co-authored-by: RevenueCat Git Bot <72824662+RCGitBot@users.noreply.github.com >
Co-authored-by: Distiller <distiller@static.38.39.183.137.cyberlynk.net >
Co-authored-by: Distiller <distiller@static.38.23.40.89.cyberlynk.net >
Co-authored-by: Distiller <distiller@static.38.39.185.65.cyberlynk.net >
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com >
2023-12-13 17:00:37 +01:00
NachoSoto
0e39c79bd9
StoreProduct: improve priceFormatter documentation (#3500 )
2023-12-10 22:27:52 -08:00
Toni Rico
4f80eda386
Improve pricePerYear price calculation precision ( #3492 )
...
### Description
Followup to #3480
This slightly improves precision when calculating price per year for
weekly subscriptions.
2023-12-05 15:41:30 +01:00
Andy Boedo
ad0f9d93ab
Improve price per month accuracy for weekly subscriptions ( #3480 )
...
We were calculating the price per month for weekly products as price *
4, but there are on average 4.345 weeks in a month, so this updates the
value accordingly.
2023-12-05 14:01:52 +01:00
NachoSoto
e31a531ca1
HTTPClient: test all request headers (#3425 )
...
This allows us to verify exactly what headers are included in all
requests.
It also simplifies the implementation for #3424 .
2023-11-17 12:19:49 -08:00
Mark Villacampa
679767adf9
Enable explicit_init lint rule and fix issues ( #3418 )
...
This rule will warn when calling `init` with the explicit type where it
can be inferred, or where the `.init` part can be omitted.
2023-11-16 00:20:00 +01:00
Josh Holtz and NachoSoto
7d78633fd8
Adds X-Storefront request header for App Store Storefront ( #3405 )
...
### Motivation
Allow backend to determine Storefront of customer
### Description
- Adds `X-Storefront` as a default header
- Uses `StoreKit 1` implementation since its not `async`
- `StoreKit 2` implementation is `async` and would require a some
restructuring that we don't need right now
---------
Co-authored-by: NachoSoto <ignaciosoto90@gmail.com >
2023-11-14 14:04:07 -08:00
NachoSoto
725d3fa827
Add StoreProduct.pricePerWeek ( #3354 )
...
This will be used to offer a new paywalls variable.
2023-11-01 08:33:44 -07:00
235a7dcdc1
StoreKit 2: Optionally send JWS tokens instead of receipts to the backend (#3227 )
...
- Added a new option `usesStoreKit2JWS` under `DangerousSettings`. If
enabled, the SDK will send a JWS token instead of a receipt to the
applicable backend endpoints.
- The option must be used in conjunction with `usesStoreKit2IfAvailable`
configuration option.
### ToDo
- [x] Send JWS token when making a purchase in SK2 mode
- [x] Send JWS token when calculating promo offer eligibility
- [x] Update `syncTransactions` to send the latest transaction JWS.
- [x] Add tests
---------
Co-authored-by: RevenueCat Git Bot <72824662+RCGitBot@users.noreply.github.com >
Co-authored-by: Distiller <distiller@static.38.39.183.118.cyberlynk.net >
Co-authored-by: Distiller <distiller@static.198.206.135.125.macminivault.com >
Co-authored-by: Distiller <distiller@static.38.23.39.112.cyberlynk.net >
Co-authored-by: Distiller <distiller@static.38.39.183.58.cyberlynk.net >
Co-authored-by: Distiller <distiller@static.38.39.185.87.cyberlynk.net >
2023-10-16 22:45:29 +02:00
NachoSoto
5db3bcb895
SK2StoreProduct.priceFormatter: use locale from StoreKit.Product (#3278 )
...
This only works in iOS 16+ (because it needs
`StoreKit.Product.priceFormatStyle`), but it's a good improvement which
ensures consistent formatting of prices in paywalls, where sometimes
`StoreProduct.localizedPrice` would have a different format compared to
formatting `pricePerMonth` using `StoreProduct.priceFormatter`.
2023-10-05 10:15:37 -07:00
NachoSoto
a08b0b3da4
Paywalls: support fuzzy-Locale search in iOS 15 (#3162 )
...
See #2847 .
Thanks to @vegaro for pointing this out.
Also removed all checks for Xcode 13 (see #3161 and #3147 ).
2023-09-14 18:28:11 -07:00
NachoSoto
1f095727d1
TestStoreProduct: new locale parameter (#3134 )
...
This allows overriding the `Locale` to be used for this test product,
which is used to configure the price formatter.
This will be used by #3133 .
2023-09-14 18:28:11 -07:00
NachoSoto
2e0feffe6a
Xcode 13: removed last Swift 5.7 checks (#3161 )
2023-09-08 07:27:11 -07:00
NachoSoto
82435936d9
Xcode 13: remove conditional code (#3147 )
...
Clean up thanks to #2421
2023-09-06 10:59:22 -07:00
NachoSoto
5d3263c8e6
TransactionPoster: don't finish transactions for non-subscriptions if they're not processed (#2841 )
2023-08-15 07:05:00 -07:00
NachoSoto
216f1e13c3
PurchasesOrchestrator: disambiguate transactions from the queue (#2890 )
...
This adds tests and a fix for a scenario discovered by @aboedo and
@mcastany.
### Timeline:
- Make a purchase of product_1
- Close app
- Renewals happen in the background
- Subscription expires
- Open app, renewals are in the queue but not processed yet
- Start a purchase of `product_1` (`SKPaymentQueue.add`)
- StoreKit queue shows renewal from step 3 as finished, it's expired
- SDK sees finished transaction in the queue for `product_1`
- SDK sees completion block for `product_1`, considers it a successful
`.purchase`
- SDK posts receipt, `initiation_source: .purchase` 💥
- Backend replies with 422 because StoreKit hasn't processed the
transaction from 6
### Fix:
The fix looks at the date when the completion block was added (the time
`.purchase()` is called).
If the transaction was created _before_ this, we know it didn't come
from the actual purchase, and therefore it should be identified as
`.queue`.
2023-08-07 15:57:10 -07:00
NachoSoto
f4fa4d2d29
SK1StoreProduct: changed productType warning to debug (#2957 )
...
See
https://community.revenuecat.com/sdks-51/purchases-purchasepackage-doesn-t-return-1956?postid=10251#post10251
Because hybrids proactively call this method to construct the internal
representation, it gets logged automatically whether they call it or
not,.
It's still useful, but making it a warning makes it seem more of a bug.
2023-08-03 12:05:57 -07:00
NachoSoto
6776347b44
TestStoreProduct: made available on release builds (#2861 )
2023-07-25 00:07:27 +02:00
NachoSoto
761ca1209d
New TestStoreProduct for creating mock StoreProducts and Offerings ( #2711 )
...
Fixes #1563 and #2193 .
This introduces **`DEBUG` and `Swift` only** types that allow creating a
whole `Offering` for tests and SwiftUI previews.
Example:

By making it available in only `DEBUG` builds we ensure that apps can't
accidentally try to purchase these products, which would be impossible.
If this is attempted in `DEBUG` builds, we return `ErrorCode`.
When trying to compile this API in release builds, you get an error with
a suggestion:

2023-06-29 14:06:24 -07:00
NachoSoto
6d60af2c42
Xcode 15: handle Locale.currencyCode deprecation (#2680 )
2023-06-22 06:23:32 -07:00
NachoSoto
01ed2cb2cf
StoreTransaction: read Storefront from StoreKit.Transaction (#2611 )
...
This was added in iOS 17, and it's potentially more accurate than
reading `Storefront.currentStorefront` later.
2023-06-12 09:35:04 -07:00
NachoSoto
e6444e2cee
StoreProductDiscount: added description (#2604 )
2023-06-09 07:42:10 -07:00
NachoSoto
6d9594ea06
Xcode 15: fixed all documentation warnings (#2596 )
2023-06-08 08:36:28 -07:00
NachoSoto
c6de563b68
SK2StoreProduct: fix crash on iOS 12 (#2565 )
2023-05-30 13:09:25 -07:00
NachoSoto
43178d89fc
StoreTransaction: implemented description (#2556 )
2023-05-30 06:49:19 -07:00
NachoSoto
c390a66014
SK2StoreProduct: simplify currencyCode extraction (#2485 )
...
I noticed this new property thanks to [this
tweet](https://twitter.com/ariskox/status/1658067009609904129?s=61&t=Zz639sMJdwHISm4AKYXoCw ).
This changes the "future" implementation of
`SK2StoreProduct.currencyCode` to use [the new (backdeployed)
property](https://developer.apple.com/documentation/storekit/product/4044347-priceformatstyle ).
We still need the existing implementation because `@_backDeploy` won't
work if compiling with `Xcode 13.x`.
2023-05-23 14:33:42 -07:00
NachoSoto
3f08a95c73
Add StoreProduct.pricePerYear ( #2462 )
2023-05-11 10:15:57 -07:00
NachoSoto and Toni Rico
4a74d33f84
Custom Entitlement Computation: disabled unnecessary APIs ( #2442 )
...
## Disabled API:
- `getCustomerInfo`
- `logIn`
- `logOut`
- `Purchases.attribution`
- `syncPurchases`
- `restorePurchases`
- Trial eligibility
- Promotional purchases
- `async` counterparts
---------
Co-authored-by: Toni Rico <antonio.rico.diez@revenuecat.com >
2023-04-26 14:51:40 -03:00
NachoSoto
2fff5b0b75
CI: also run tests on watchOS (#2340 )
...
This is a follow up to #717 .
In order to be able to reproduce #2338 , which seems to be an issue only
on `watchOS`, it's important that we now run tests on `watchOS` as well.
We probably won't be able to fully replicate that issue since we don't
run tests on actual devices, so they'll still run on 64 bits. But this
way we might be able to prevent issues that are only reproducible on
`watchOS` in the future.
## Changes:
- Added CircleCI job
- Added lane
- Simplified `UnitTestsHostApp` definition using `SwiftUI`
- Increased _test only_ `watchOS` deployment target to 7.0 (this was
necessary to be able to have a common `@main` for the host app)
- Increased _test only_ `tvOS` deployment target to `14.0` (same as
above, plus we only run tvOS tests on the latest version anyway. We test
backwards compatibility through iOS already)
- Fixed test compilation on `watchOS`
- Disabled `HTTPClient` tests on `watchOS` (see
https://github.com/AliSoftware/OHHTTPStubs/issues/287 )
- `StoreKitConfigTestCase` is only available from `watchOS 7.0` since
that's when `SKTestSession` was introduced
- Added `watchOS` support to `UnitTests` target
- Added `watchOS` support to `ReceiptParserTests` target
- Fixed `isFamilySharable` `watchOS` version checks for version 8.0
- Created new `CI-RevenueCat` Test Plan to only run unit tests and not
StoreKit tests on `watchOS`
2023-03-16 13:11:24 -07:00
Andy Boedo
fdfece85b6
clarifies error messages for storekit 1 bugs ( #2294 )
...
We have a few error messages for StoreKit 1 bugs that look pretty scary.
However, they really aren't - while they surface genuine bugs in
StoreKit, they require no action on the developer's side, and our
backend won't be affected. So in practice, they're not useful.
This PR updates the copy so that:
- it doesn't suggest using SK2
- it moves from `warn` to `verbose`, since there's really no action on
the developer's side needed
- it clarifies what's going on under the hood
| Before | After |
| :-: | :-: |
| <img width="1311" alt="Screenshot 2023-02-17 at 3 43 02 PM"
src="https://user-images.githubusercontent.com/3922667/219758984-c9593d12-23fb-4076-ab87-2c5454f7084b.png ">
| <img width="1304" alt="Screenshot 2023-02-17 at 3 52 05 PM"
src="https://user-images.githubusercontent.com/3922667/219759107-9abdb01b-f626-41de-b20c-a08bbd6c1c05.png ">
|
2023-02-17 15:05:37 -08:00
NachoSoto
32d10a9fbd
StoreKit2StorefrontListener: added tests to fix flaky code coverage (#2265 )
...
Similarly to #2262 , test execution ordering was leading to [flaky code
coverage
results](https://app.codecov.io/gh/RevenueCat/purchases-ios/pull/2262 )
with this.

Because we didn't have any test coverage, only if some other test
changed the `Storefront`, this test was calling the delegate code.
This adds explicit test coverage using a `MockAsyncSequence`.
### Other changes:
- Added `StorefrontType` to `StoreKit2StorefrontListenerDelegate` method
- `Storefront` initializers are no longer `Optional` `init?`
- Simplified `StoreKit2StorefrontListenerTests` by moving
`AvailabilityChecks` to `setUp`
2023-02-08 12:45:08 -08:00
NachoSoto
cf3090a858
Replaced Any uses for workaround with Box ( #2250 )
2023-02-07 06:51:29 -08:00
NachoSoto
1b13754ca2
Fixed race condition finishing SK1 transactions ( #2148 )
...
Fixes [CSDK-504].
`SKPaymentQueue.finishTransaction` is asynchronous, but we were assuming
it wasn't.
This meant that when performing multiple purchases (like consumables) in
quick succession, before the first transaction was finished, the second
purchase was reusing the first transaction.
Example log:
```
[Purchases] - INFO: 💰 Finishing transaction ‘0’ for product ‘consumable.10_coins’
[Purchases] - INFO: 😻 💰 Purchased product - ‘consumable.10_coins’
[Purchases] - INFO: 💰 Purchasing Product ‘consumable.10_coins’ from package in Offering ‘coins’
[Purchases] - DEBUG: ℹ️ StoreKit1Wrapper (0x00006000008a9530) removedTransaction: consumable.10_coins 0 1
```
Notice how the "removed transaction" was notified _after_ we had already
started the second purchase.
See also #2148 for an earlier fix for finishing transactions.
[CSDK-504]:
https://revenuecats.atlassian.net/browse/CSDK-504?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
2022-12-21 08:17:07 -08:00
NachoSoto
8e32400c4e
Fixed purchasing with PromotionalOffers using StoreKit 2 ( #2020 )
...
Fixes [SDKONCALL-160], [SDKONCALL-182], #2114 , and
https://github.com/RevenueCat/react-native-purchases/issues/455 .
Depends on #2118 and https://github.com/RevenueCat/khepri/pull/4843 /
https://github.com/RevenueCat/khepri/pull/4852 .
## Changes:
- Base64decode `signature`
- Fixed signature on backend for SK2:
https://github.com/RevenueCat/khepri/pull/4843 /
https://github.com/RevenueCat/khepri/pull/4852
- Added tests
- Added specific error if signature can't be decoded:
> [Purchases] - ERROR: 😿 ‼️ The information associated with this
PromotionalOffer is not valid.
See https://rev.cat/ios-subscription-offers for more info. The signature
generated by RevenueCat could not be decoded: signature 914
[SDKONCALL-160]:
https://revenuecats.atlassian.net/browse/SDKONCALL-160?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[SDKONCALL-182]:
https://revenuecats.atlassian.net/browse/SDKONCALL-182?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
2022-12-09 15:04:29 -08:00
Bas Broek
70209e58dc
Fix documentation typo ( #2113 )
...
<!-- Thank you for contributing to Purchases! Before pressing the
"Create Pull Request" button, please provide the following: -->
### Checklist
- [ ] If applicable, unit tests
- [ ] If applicable, create follow-up issues for `purchases-android` and
hybrids
### Motivation
<!-- Why is this change required? What problem does it solve? -->
<!-- Please link to issues following this format: Resolves #999999 -->
Just a documentation header typo :)
### Description
<!-- Describe your changes in detail -->
<!-- Please describe in detail how you tested your changes -->
`ccurrency` -> `currency`
2022-12-02 14:31:57 -03:00
NachoSoto
70365df383
Purchasing: fixed consumable purchases by fixing transaction-finishing ( #1965 )
...
Fixes #1964 , [TRIAGE-134], [TRIAGE-131], and possibly [TRIAGE-82].
Depends on #1967 , #1968 .
### Fixes:
- For `SK2` purchases we were never finishing transactions. We are now.
- For `SK1` purchases, transactions were finished _after_ the completion
block was invoked (and tests were very lenient checking that
_eventually_ this happened). This could have lead to race conditions.
- For SK2 only (at least in `SKTestSession`s), this fixes the ability to
purchase multiple consumable purchases.
This is the log from the failing test using SK2:
<details>
<summary>Open</summary>
```
2022-10-06 15:18:52.286813-0700 BackendIntegrationTestsHostApp[45464:7076968] [Purchases] - DEBUG: ℹ️ API request started: GET /v1/subscribers/$RCAnonymousID:6f630d50b8294288a2d0862629d766fb/offerings
2022-10-06 15:18:52.383594-0700 BackendIntegrationTestsHostApp[45464:7076968] [Purchases] - DEBUG: ℹ️ API request completed: GET /v1/subscribers/$RCAnonymousID:6f630d50b8294288a2d0862629d766fb/offerings 200
2022-10-06 15:18:52.388247-0700 BackendIntegrationTestsHostApp[45464:7076968] [Purchases] - DEBUG: ℹ️ No existing products cached, starting store products request for: ["com.revenuecat.weekly_1.99.3_day_intro", "consumable.10_coins", "com.revenuecat.annual_39.99.2_week_intro", "com.revenuecat.monthly_4.99.1_week_intro"]
2022-10-06 15:18:52.388382-0700 BackendIntegrationTestsHostApp[45464:7076968] [Purchases] - DEBUG: ℹ️ Found an existing request for products: ["com.revenuecat.monthly_4.99.1_week_intro", "com.revenuecat.annual_39.99.2_week_intro", "com.revenuecat.weekly_1.99.3_day_intro", "consumable.10_coins"], appending to completion
2022-10-06 15:18:52.388451-0700 BackendIntegrationTestsHostApp[45464:7076968] [Purchases] - DEBUG: ℹ️ GetOfferingsOperation: Finished
2022-10-06 15:18:52.388560-0700 BackendIntegrationTestsHostApp[45464:7076968] [Purchases] - DEBUG: ℹ️ Serial request done: GET subscribers/$RCAnonymousID%3A6f630d50b8294288a2d0862629d766fb/offerings, 0 requests left in the queue
2022-10-06 15:18:52.420210-0700 BackendIntegrationTestsHostApp[45464:7076968] [Purchases] - DEBUG: 😻 Store products request request received response
2022-10-06 15:18:52.420358-0700 BackendIntegrationTestsHostApp[45464:7076968] [Purchases] - DEBUG: ℹ️ Store products request finished
2022-10-06 15:18:52.421126-0700 BackendIntegrationTestsHostApp[45464:7076978] [Purchases] - DEBUG: ℹ️ Vending Offerings from cache
2022-10-06 15:18:52.421353-0700 BackendIntegrationTestsHostApp[45464:7076968] [Purchases] - INFO: 💰 Purchasing Product 'consumable.10_coins' from package in Offering 'coins'
2022-10-06 15:18:52.496438-0700 BackendIntegrationTestsHostApp[45464:7076968] [Purchases] - DEBUG: ℹ️ Force refreshing the receipt to get latest transactions from Apple.
2022-10-06 15:18:52.510974-0700 BackendIntegrationTestsHostApp[45464:7076903] [Purchases] - DEBUG: ℹ️ Loaded receipt from url file:///Users/nachosoto/Library/Developer/CoreSimulator/Devices/A3576DC2-355E-45BA-B32C-D2C0A3811BB4/data/Containers/Data/Application/BFD385C4-52BC-414B-9C1C-44522ED1222F/StoreKit/receipt
2022-10-06 15:18:52.511072-0700 BackendIntegrationTestsHostApp[45464:7076903] [Purchases] - DEBUG: ℹ️ Skipping products request because products were already cached. products: ["consumable.10_coins"]
2022-10-06 15:18:52.511181-0700 BackendIntegrationTestsHostApp[45464:7076903] [Purchases] - DEBUG: ℹ️ Skipping products request because products were already cached. products: ["consumable.10_coins"]
2022-10-06 15:18:52.511564-0700 BackendIntegrationTestsHostApp[45464:7076903] [Purchases] - DEBUG: ℹ️ Found 0 unsynced attributes for App User ID: $RCAnonymousID:6f630d50b8294288a2d0862629d766fb
2022-10-06 15:18:52.515448-0700 BackendIntegrationTestsHostApp[45464:7076978] [Purchases] - DEBUG: ℹ️ PostReceiptDataOperation: Started
2022-10-06 15:18:52.516403-0700 BackendIntegrationTestsHostApp[45464:7076978] [Purchases] - INFO: ℹ️ Receipt parsed successfully
2022-10-06 15:18:52.516763-0700 BackendIntegrationTestsHostApp[45464:7076978] [Purchases] - DEBUG: ℹ️ PostReceiptDataOperation: Posting receipt: {
"opaque_value" : "oX91ewAAAAA=",
"sha1_hash" : "GsyNpUKQ89SonYyj\/jpw8\/N5nr8=",
"bundle_id" : "com.revenuecat.StoreKitTestApp",
"in_app_purchases" : [
{
"quantity" : 1,
"product_id" : "consumable.10_coins",
"purchase_date" : "2022-10-06T22:18:52Z",
"transaction_id" : "0"
}
],
"application_version" : "1",
"creation_date" : "2022-10-06T22:18:52Z",
"expiration_date" : "4001-01-01T00:00:00Z"
}
2022-10-06 15:18:52.516825-0700 BackendIntegrationTestsHostApp[45464:7076978] [Purchases] - DEBUG: ℹ️ There are no requests currently running, starting request POST receipts
2022-10-06 15:18:52.518059-0700 BackendIntegrationTestsHostApp[45464:7076978] [Purchases] - DEBUG: ℹ️ API request started: POST /v1/receipts
2022-10-06 15:18:52.960048-0700 BackendIntegrationTestsHostApp[45464:7076966] [Purchases] - DEBUG: ℹ️ API request completed: POST /v1/receipts 200
2022-10-06 15:18:52.964274-0700 BackendIntegrationTestsHostApp[45464:7076966] [Purchases] - DEBUG: ℹ️ PostReceiptDataOperation: Finished
2022-10-06 15:18:52.964666-0700 BackendIntegrationTestsHostApp[45464:7076966] [Purchases] - DEBUG: ℹ️ Serial request done: POST receipts, 0 requests left in the queue
2022-10-06 15:18:52.966476-0700 BackendIntegrationTestsHostApp[45464:7076903] [Purchases] - DEBUG: ℹ️ Sending updated CustomerInfo to delegate.
2022-10-06 15:18:52.966697-0700 BackendIntegrationTestsHostApp[45464:7076966] [Purchases] - INFO: 😻 💰 Purchased product - 'consumable.10_coins'
2022-10-06 15:18:52.966973-0700 BackendIntegrationTestsHostApp[45464:7076966] [Purchases] - DEBUG: ℹ️ Vending Offerings from cache
2022-10-06 15:18:52.967284-0700 BackendIntegrationTestsHostApp[45464:7076966] [Purchases] - INFO: 💰 Purchasing Product 'consumable.10_coins' from package in Offering 'coins'
2022-10-06 15:18:52.991334-0700 BackendIntegrationTestsHostApp[45464:7076973] [Purchases] - DEBUG: ℹ️ Force refreshing the receipt to get latest transactions from Apple.
2022-10-06 15:18:53.015046-0700 BackendIntegrationTestsHostApp[45464:7076903] [Purchases] - DEBUG: ℹ️ Loaded receipt from url file:///Users/nachosoto/Library/Developer/CoreSimulator/Devices/A3576DC2-355E-45BA-B32C-D2C0A3811BB4/data/Containers/Data/Application/BFD385C4-52BC-414B-9C1C-44522ED1222F/StoreKit/receipt
2022-10-06 15:18:53.015174-0700 BackendIntegrationTestsHostApp[45464:7076903] [Purchases] - DEBUG: ℹ️ Skipping products request because products were already cached. products: ["consumable.10_coins"]
2022-10-06 15:18:53.015262-0700 BackendIntegrationTestsHostApp[45464:7076903] [Purchases] - DEBUG: ℹ️ Skipping products request because products were already cached. products: ["consumable.10_coins"]
2022-10-06 15:18:53.015419-0700 BackendIntegrationTestsHostApp[45464:7076903] [Purchases] - DEBUG: ℹ️ Found 0 unsynced attributes for App User ID: $RCAnonymousID:6f630d50b8294288a2d0862629d766fb
2022-10-06 15:18:53.015927-0700 BackendIntegrationTestsHostApp[45464:7076966] [Purchases] - DEBUG: ℹ️ PostReceiptDataOperation: Started
2022-10-06 15:18:53.016558-0700 BackendIntegrationTestsHostApp[45464:7076966] [Purchases] - INFO: ℹ️ Receipt parsed successfully
2022-10-06 15:18:53.016727-0700 BackendIntegrationTestsHostApp[45464:7076966] [Purchases] - DEBUG: ℹ️ PostReceiptDataOperation: Posting receipt: {
"opaque_value" : "LP9LZQwAAAA=",
"sha1_hash" : "WdANBTWr7wYWh8RYEgmGebO8DR8=",
"bundle_id" : "com.revenuecat.StoreKitTestApp",
"in_app_purchases" : [
{
"quantity" : 1,
"product_id" : "consumable.10_coins",
"purchase_date" : "2022-10-06T22:18:52Z",
"transaction_id" : "0"
}
],
"application_version" : "1",
"creation_date" : "2022-10-06T22:18:53Z",
"expiration_date" : "4001-01-01T00:00:00Z"
}
2022-10-06 15:18:53.016783-0700 BackendIntegrationTestsHostApp[45464:7076966] [Purchases] - DEBUG: ℹ️ There are no requests currently running, starting request POST receipts
2022-10-06 15:18:53.017602-0700 BackendIntegrationTestsHostApp[45464:7076966] [Purchases] - DEBUG: ℹ️ API request started: POST /v1/receipts
2022-10-06 15:18:53.411689-0700 BackendIntegrationTestsHostApp[45464:7076978] [Purchases] - DEBUG: ℹ️ API request completed: POST /v1/receipts 200
2022-10-06 15:18:53.413980-0700 BackendIntegrationTestsHostApp[45464:7076978] [Purchases] - DEBUG: ℹ️ PostReceiptDataOperation: Finished
2022-10-06 15:18:53.414147-0700 BackendIntegrationTestsHostApp[45464:7076978] [Purchases] - DEBUG: ℹ️ Serial request done: POST receipts, 0 requests left in the queue
2022-10-06 15:18:53.414927-0700 BackendIntegrationTestsHostApp[45464:7076978] [Purchases] - INFO: 😻 💰 Purchased product - 'consumable.10_coins'
2022-10-06 15:18:53.415505-0700 BackendIntegrationTestsHostApp[45464:7076978] [Purchases] - DEBUG: ℹ️ Vending CustomerInfo from cache.
```
</details>
With the fix, you can see transactions are now finished at the right
time:
<details>
<summary>Open</summary>
```
2022-10-07 11:08:01.967843-0700 BackendIntegrationTestsHostApp[45714:674592] [Purchases] - INFO: 💰 Purchasing Product 'consumable.10_coins' from package in Offering 'coins'
2022-10-07 11:08:02.123611-0700 BackendIntegrationTestsHostApp[45714:674592] [Purchases] - DEBUG: ℹ️ Force refreshing the receipt to get latest transactions from Apple.
2022-10-07 11:08:02.138918-0700 BackendIntegrationTestsHostApp[45714:674399] [Purchases] - DEBUG: ℹ️ Loaded receipt from url file:///Users/nachosoto/Library/Developer/CoreSimulator/Devices/F02A9A20-949B-4C9D-A01E-AB0CC7544F96/data/Containers/Data/Application/C52A5EFD-733F-46EC-84B7-734B6AF9D28C/StoreKit/receipt
2022-10-07 11:08:02.139013-0700 BackendIntegrationTestsHostApp[45714:674399] [Purchases] - DEBUG: ℹ️ Skipping products request because products were already cached. products: ["consumable.10_coins"]
2022-10-07 11:08:02.139095-0700 BackendIntegrationTestsHostApp[45714:674399] [Purchases] - DEBUG: ℹ️ Skipping products request because products were already cached. products: ["consumable.10_coins"]
2022-10-07 11:08:02.139481-0700 BackendIntegrationTestsHostApp[45714:674399] [Purchases] - DEBUG: ℹ️ Found 0 unsynced attributes for App User ID: $RCAnonymousID:bd74b9d10f2c48eea1d741a32f5acb16
2022-10-07 11:08:02.147220-0700 BackendIntegrationTestsHostApp[45714:674592] [Purchases] - DEBUG: ℹ️ PostReceiptDataOperation: Started
2022-10-07 11:08:02.148192-0700 BackendIntegrationTestsHostApp[45714:674592] [Purchases] - INFO: ℹ️ Receipt parsed successfully
2022-10-07 11:08:02.148552-0700 BackendIntegrationTestsHostApp[45714:674592] [Purchases] - DEBUG: ℹ️ PostReceiptDataOperation: Posting receipt: {
"opaque_value" : "\/3nevQ0AAAA=",
"sha1_hash" : "\/bAkxLQ6BPgUg3rR9jDR28dEfig=",
"bundle_id" : "com.revenuecat.StoreKitTestApp",
"in_app_purchases" : [
{
"quantity" : 1,
"product_id" : "consumable.10_coins",
"purchase_date" : "2022-10-07T18:08:02Z",
"transaction_id" : "0"
}
],
"application_version" : "1",
"creation_date" : "2022-10-07T18:08:02Z",
"expiration_date" : "4001-01-01T00:00:00Z"
}
2022-10-07 11:08:02.148604-0700 BackendIntegrationTestsHostApp[45714:674592] [Purchases] - DEBUG: ℹ️ There are no requests currently running, starting request POST receipts
2022-10-07 11:08:02.149748-0700 BackendIntegrationTestsHostApp[45714:674592] [Purchases] - DEBUG: ℹ️ API request started: POST /v1/receipts
2022-10-07 11:08:02.733225-0700 BackendIntegrationTestsHostApp[45714:674602] [Purchases] - DEBUG: ℹ️ API request completed: POST /v1/receipts 200
2022-10-07 11:08:02.734687-0700 BackendIntegrationTestsHostApp[45714:674602] [Purchases] - DEBUG: ℹ️ PostReceiptDataOperation: Finished
2022-10-07 11:08:02.734802-0700 BackendIntegrationTestsHostApp[45714:674602] [Purchases] - DEBUG: ℹ️ Serial request done: POST receipts, 0 requests left in the queue
2022-10-07 11:08:02.735631-0700 BackendIntegrationTestsHostApp[45714:674399] [Purchases] - DEBUG: ℹ️ Sending updated CustomerInfo to delegate.
2022-10-07 11:08:02.735700-0700 BackendIntegrationTestsHostApp[45714:674399] [Purchases] - INFO: 💰 Finishing transaction '0' for product 'consumable.10_coins'
2022-10-07 11:08:02.760613-0700 BackendIntegrationTestsHostApp[45714:674592] [Purchases] - INFO: 😻 💰 Purchased product - 'consumable.10_coins'
2022-10-07 11:08:02.760828-0700 BackendIntegrationTestsHostApp[45714:674590] [Purchases] - DEBUG: ℹ️ Vending Offerings from cache
2022-10-07 11:08:02.761032-0700 BackendIntegrationTestsHostApp[45714:674590] [Purchases] - INFO: 💰 Purchasing Product 'consumable.10_coins' from package in Offering 'coins'
2022-10-07 11:08:02.820835-0700 BackendIntegrationTestsHostApp[45714:674589] [Purchases] - DEBUG: ℹ️ Force refreshing the receipt to get latest transactions from Apple.
2022-10-07 11:08:02.839184-0700 BackendIntegrationTestsHostApp[45714:674399] [Purchases] - DEBUG: ℹ️ Loaded receipt from url file:///Users/nachosoto/Library/Developer/CoreSimulator/Devices/F02A9A20-949B-4C9D-A01E-AB0CC7544F96/data/Containers/Data/Application/C52A5EFD-733F-46EC-84B7-734B6AF9D28C/StoreKit/receipt
2022-10-07 11:08:02.839275-0700 BackendIntegrationTestsHostApp[45714:674399] [Purchases] - DEBUG: ℹ️ Skipping products request because products were already cached. products: ["consumable.10_coins"]
2022-10-07 11:08:02.839348-0700 BackendIntegrationTestsHostApp[45714:674399] [Purchases] - DEBUG: ℹ️ Skipping products request because products were already cached. products: ["consumable.10_coins"]
2022-10-07 11:08:02.839476-0700 BackendIntegrationTestsHostApp[45714:674399] [Purchases] - DEBUG: ℹ️ Found 0 unsynced attributes for App User ID: $RCAnonymousID:bd74b9d10f2c48eea1d741a32f5acb16
2022-10-07 11:08:02.839911-0700 BackendIntegrationTestsHostApp[45714:674589] [Purchases] - DEBUG: ℹ️ PostReceiptDataOperation: Started
2022-10-07 11:08:02.840457-0700 BackendIntegrationTestsHostApp[45714:674589] [Purchases] - INFO: ℹ️ Receipt parsed successfully
2022-10-07 11:08:02.840603-0700 BackendIntegrationTestsHostApp[45714:674589] [Purchases] - DEBUG: ℹ️ PostReceiptDataOperation: Posting receipt: {
"opaque_value" : "fXr9\/QYAAAA=",
"sha1_hash" : "zreYwGKGSaOEww1bsTRu8MylAas=",
"bundle_id" : "com.revenuecat.StoreKitTestApp",
"in_app_purchases" : [
{
"quantity" : 1,
"product_id" : "consumable.10_coins",
"purchase_date" : "2022-10-07T18:08:02Z",
"transaction_id" : "1"
}
],
"application_version" : "1",
"creation_date" : "2022-10-07T18:08:02Z",
"expiration_date" : "4001-01-01T00:00:00Z"
}
2022-10-07 11:08:02.840662-0700 BackendIntegrationTestsHostApp[45714:674589] [Purchases] - DEBUG: ℹ️ There are no requests currently running, starting request POST receipts
2022-10-07 11:08:02.841268-0700 BackendIntegrationTestsHostApp[45714:674589] [Purchases] - DEBUG: ℹ️ API request started: POST /v1/receipts
2022-10-07 11:08:03.313116-0700 BackendIntegrationTestsHostApp[45714:674589] [Purchases] - DEBUG: ℹ️ API request completed: POST /v1/receipts 200
2022-10-07 11:08:03.316115-0700 BackendIntegrationTestsHostApp[45714:674589] [Purchases] - DEBUG: ℹ️ PostReceiptDataOperation: Finished
2022-10-07 11:08:03.316342-0700 BackendIntegrationTestsHostApp[45714:674589] [Purchases] - DEBUG: ℹ️ Serial request done: POST receipts, 0 requests left in the queue
2022-10-07 11:08:03.317444-0700 BackendIntegrationTestsHostApp[45714:674399] [Purchases] - DEBUG: ℹ️ Sending updated CustomerInfo to delegate.
2022-10-07 11:08:03.317527-0700 BackendIntegrationTestsHostApp[45714:674399] [Purchases] - INFO: 💰 Finishing transaction '1' for product 'consumable.10_coins'
2022-10-07 11:08:03.342767-0700 BackendIntegrationTestsHostApp[45714:674602] [Purchases] - INFO: 😻 💰 Purchased product - 'consumable.10_coins'
```
</details>
[TRIAGE-134]:
https://revenuecats.atlassian.net/browse/TRIAGE-134?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[TRIAGE-131]:
https://revenuecats.atlassian.net/browse/TRIAGE-131?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[TRIAGE-82]:
https://revenuecats.atlassian.net/browse/TRIAGE-82?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
2022-10-11 13:38:54 -07:00
NachoSoto
b746f5f205
PaymentQueueWrapper: improved abstraction for active SKPaymentQueue wrapper (#1968 )
...
This is a follow up to #1901 and #1882 . Depends on #1967 .
Essentially before this change, `Purchases` had both `StoreKit1Wrapper?`
and a `PaymentQueueWrapper`. The later wasn't actually needed when the
first was not-nil, so it was essentially storing `(a?, b?)`. What we
really wanted to express is that it could have one OR the other.
This introduces `Either` to express this requirement in the type system,
as well as `PaymentQueueWrapperType` that will be used to fix #1964 .
2022-10-11 12:55:42 -07:00
NachoSoto
9e4b329f99
Moved SKPaymentQueue.presentCodeRedemptionSheet to StoreKitWorkarounds ( #1967 )
...
NFC.
I'll be using this method from 2 different places, and it belongs here
with the other workarounds.
2022-10-10 08:38:59 -07:00
Andy Boedo
cc81b3fa86
fix typo in comment ( #1956 )
...
Super high risk, dangerous PR with complicated changes, do not merge
2022-09-29 11:33:51 -03:00
NachoSoto
72a9f57103
PaymentQueueWrapper: handle promotional purchase requests from App Store when SK1 is disabled (#1901 )
...
Follow up to #1882 . After that PR, `StoreKit1Wrapper` was no longer
listening to
`SKPaymentQueueDelegate.paymentQueue(:shouldAddStorePayment:for:)`,
which means that purchases initiated from the App Store were being
ignored by the SDK if SK2 is enabled.
To fix this, `PaymentQueueWrapper` now becomes the
`SKPaymentQueueDelegate` only when `StoreKit1Wrapper` is not
initialized, and `PurchasesOrchestrator` initiates an SK2 purchase
instead.
## Other changes:
- `PurchasesOrchestrator` purchase methods no longer need the whole
`PromotionalOffer`, only the `SignedData`. This allows the new
implementation to create that data from only the `SKPaymentDiscount`
provided from the `SKPayment`.
- Added tests for `PromotionalOffer.SignedData`
2022-09-21 12:03:05 -07:00
NachoSoto
7934faf4a6
Renamed StoreKitWrapper to StoreKit1Wrapper ( #1886 )
...
Follow up to #1882 . Now that `StoreKit1Wrapper` is not initialized for SK2, it makes sense to clarify that this class is only for SK1.
This is just a simple find-replace.
2022-09-06 17:15:54 -05:00