Repository navigation
Commerce: offerings, paywalls, customer center, more stores, and invites - #6219
shai-almog wants to merge 21 commits into
Conversation
…ager refresh() now asks the service for the customer after validating the device's receipts, even when there are none, and takes that answer as the entitlement state. The last accepted answer is stored per app user id and read back on a cold start. Answers of the new endpoints are verified with Ed25519 over the request nonce when a public key is known. Adds CustomerInfo and EntitlementInfo, logIn, logOut, restore, setAttributes, customer listeners, and a refresh after every successful receipt synchronization. Commerce requests no longer raise the framework's error dialog on an error status. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
CommerceManager reads commerce.cloud.enabled, commerce.cloud.endpoint and commerce.cloud.publicKey through Display.getProperty. They were declared in no catalog and stamped by no builder, so a build accepted them and nothing read them. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
CommerceManager fetches the offerings of a customer (stored for when the network fails, with the store's products attached to the packages), buys a package, and queues paywall events that a background thread sends in one request. PaywallView builds a paywall document from standard components with documented UIIDs; CustomerCenter shows the configured paths over the active subscriptions. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The StoreKit natives were already shared with the macOS port and compiled to nothing there: the builder never defined CN1_USE_STOREKIT, the delegate methods sat inside the UIKit controller's @implementation, which macOS compiles out, and nothing observed the payment queue. - The StoreKit delegate moves into a category on CodenameOne_GLViewController, so the UIKit controller and the AppKit render driver run the same product, transaction and receipt code. - macOS builds a payment from an SKProduct, as tvOS does; the SDK marks paymentWithProductIdentifier: unavailable on both. - The receipt posted is the app receipt under the same store code. - MacOSNativeBuilder switches the define on for an application that uses com.codename1.payment and declares StoreKit.framework, for the review prompt as well, which had been linking through an autolink hint. - Manage subscriptions opens the https address on macOS. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The android.billing.store build hint (play, the default, or amazon) picks the store an in-app-purchase app is built for. An Amazon build depends on the Amazon Appstore SDK instead of Play Billing, declares the receiver Amazon's client answers through, and does not request com.android.vending.BILLING or require android.licenseKey. AmazonBillingSupport is the port's implementation over the SDK's IAP API. Like BillingSupport it ships as source: the port's module build excludes it, and the builder keeps only the source whose library the build carries and names that class in the generated activity stub. Receipts carry the new store code Receipt.STORE_CODE_AMAZON, which CommerceManager sends as store "amazon". Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…c store on the client A package with no product of the platform's store is sold through a hosted checkout where the platform has no store, a web subscription is managed in the billing portal, and a retention offer that names a promotional offer is bought with a signature from the cloud. Receipts of the Mac App Store are sent under their own store name. The commerce build hints are stamped into the Linux, Windows, macOS, JavaScript and watch stubs as well, and the simulator resolves them from the project settings. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
… and the service API Covers entitlements and the stored answer, identity and transfer policies, offerings and packages, targeting and experiments, paywalls and their document format, the customer center, attributes and virtual currency, the stores (Apple, Google Play, Amazon, Stripe and Paddle), webhooks, integrations, the REST API, export and import, the build hints and the simulator. Every sample is a compiled snippet. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…e or restore completes Paywall.show closes its form before the listener hears purchaseCompleted or restoreCompleted; an embedded PaywallView stays where it is. Also clears the SpotBugs and PMD findings the gates reported in CommerceManager and PaywallView. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…referral rewards Every commerce request carries the install's analytics client id when a provider is registered and consent covers analytics, so the service can join a customer to that install's analytics and invite records. The paywall and the customer center report their events through the analytics providers, with the placement and the experiment variant of the offering, and Purchase's own purchase events gain that context for a purchase started from a package. An experiment assignment is reported once as an exposure. An invite attribution refreshes the customer in the background through an observer on Analytics that leaves the application's InviteListener alone, and CustomerInfo lists the referral rewards the service granted. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…he paywall and customer center Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ned envelope, http endpoints only on loopback With no public key known, no signed-envelope answer is used or cached; the manager stays degraded and answers from the store. The cold-start cache keeps the envelope and verifies it again on load. Analytics re-notifies the attribution observer after attribution was cleared. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…vice endpoints With a public key the validate request carries a nonce and goes through postSigned; an unsigned or forged answer applies nothing. Without a key the request is still sent but its answer is ignored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…referral rewards and Amazon SNS Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…und to another user, package or endpoint are refused Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h touched Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eForeach) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cloud answers are now verified out of the box. The tests that cover the no-key path clear a package-private override, since no shipped build can reach that path any more. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Developer Guide build artifacts are available for download from this workflow run:
Developer Guide quality checks: |
|
Compared 12 screenshots: 12 matched. |
✅ Continuous Quality ReportTest & Coverage
Static Analysis
Generated automatically by the PR CI workflow. |
|
Compared 195 screenshots: 195 matched. Native Android coverage
✅ Native Android screenshot tests passed. Native Android coverage
Benchmark ResultsDetailed Performance Metrics
|
|
Compared 231 screenshots: 231 matched. |
✅ ByteCodeTranslator Quality ReportTest & Coverage
Benchmark Results
Static Analysis
Generated automatically by the PR CI workflow. |
|
Compared 210 screenshots: 210 matched. Benchmark ResultsDetailed Performance Metrics
ParparVM vs HotSpot (JDK 25): Windows x64Runner CPU: AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in
Result: no regression |
|
Compared 210 screenshots: 210 matched. Benchmark ResultsDetailed Performance Metrics
ParparVM vs HotSpot (JDK 25): Windows arm64Runner CPU: ARMv8 (64-bit) Family 8 Model D49 Revision 0, MICROSOFT CORPORATION (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in
Result: no regression |
|
Compared 210 screenshots: 210 matched. ParparVM vs HotSpot (JDK 25): Linux x64Runner CPU: AMD EPYC 9V74 80-Core Processor (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in
Result: no regression |
|
Compared 210 screenshots: 210 matched. ParparVM vs HotSpot (JDK 25): Linux arm64Runner CPU: Neoverse-N2 (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in
Result: no regression |
|
Compared 196 screenshots: 196 matched. Benchmark Results
Detailed Performance Metrics
ParparVM vs HotSpot (JDK 25): macOS arm64Runner CPU: Apple M1 (Virtual) (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in
Result: no regression |
…builds The port's exclusion list lives in three files and only the Maven copy had the Amazon billing class, so the Ant build failed on the missing Appstore SDK. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cloudflare Preview
|
… hint Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Commerce gets the full subscription product surface on the client: customer info, offerings, paywalls, a customer center, web checkout, and more stores, all tied into Codename One's own analytics and invite-a-friend.
What's in it
logIn/logOut, attributes, restore, a cached cold start, and a listener for changes.getOfferings()returns what the console configured, with targeting and experiments.PaywallViewrenders the console's paywall from native components, with a bundled default when the cloud has none.Ports/MacPort), Amazon Appstore (android.billing.store=amazon), and web checkout through Stripe or Paddle (purchaseOnWeb,fetchManagementUrl). Apple promotional offers are signed by the service.CustomerInfo.getReferralRewards()with no app code.httpendpoints are accepted only on loopback. The production public key is built in.commerce.cloud.enabled,commerce.cloud.endpoint,commerce.cloud.publicKeyandandroid.billing.store, declared in the catalog and stamped by every builder.Verification
purchase-e2enow asserts this). The StoreKitTest purchase itself still needs this job's run.Goes with codenameone/BuildCloud and codenameone/BuildDaemon branches
commerce-parity.🤖 Generated with Claude Code