PubliraGitHub

이 페이지는 최신 릴리스가 아닌 v0.2 버전을 설명합니다. 최신 릴리스는 v0.3 문서를 참고하세요.

이 페이지는 아직 한국어로 번역되지 않아 영어로 표시됩니다.

In-app purchase and sign-in

게시 업데이트

Selling episodes and signing in with Apple or Google are set up once for the whole tenant, in the tenant console, and the site and the app share that setup. This page covers what is particular to the app: the parts of each store's and each provider's console that only the app needs, and how the app decides what to offer. The app's build needs nothing for either beyond the manifest and App links, except the Google client named in the manifest for Google sign-in on iOS.

All of them rely on Integrations › App links: the store sections of in-app purchase sell in the apps named there, Sign in with Apple trusts the apps named there, and the site shares its passkeys with the apps named there. Fill it in first.

Selling episodes in the app

Under Payments › Payment methods, two settings decide what the app offers on a paid episode:

  • Where episodes are sold decides whether an episode can be bought in the app at all: Web and app, Web only, or App only. A series or an episode can override it.
  • How the app sells episodes, in the In-app purchase section, decides how the app sells an episode it may sell. Web checkout opens the site's checkout in the phone's browser and brings the reader back to the episode once paid. In-app purchase sells with the store's own payment sheet, and the store charges the reader and keeps its commission.

The App Store and Google Play each have rules on how an app may sell digital content, and they decide in review whether an app follows them. Read their current guidelines before choosing Web checkout for an app you submit.

What each store needs for in-app purchase

The app sells each episode as a store product named after its price. Store products, on the same console page, lists the product ID each price your paid episodes sell at needs, such as episode_300. Create every listed product in both stores, as a consumable product at that price, and add one whenever a new price appears in the list.

In App Store Connect:

  • Accept the Paid Apps agreement, and complete the banking and tax details it asks for. No product can be sold until it is in effect.
  • Create the listed products under the app's In-App Purchases, as consumables.
  • Create the key the install verifies purchases with, and enter its Issuer ID, Key ID, and Private key (.p8) under the App Store section of In-app purchase.
  • Enter the App Store Server Notifications URL the console shows as both the Production and the Sandbox Server URL, under the app's App Information. A refund Apple reports there takes the episode back from the reader.

In Play Console:

  • Set up a payments profile, so the account can sell.
  • Upload an App Bundle to a testing track before creating products. Play Console can refuse products for an app that has not yet uploaded a build that uses Google Play's billing, which every Publira build does.
  • Create the listed products as one-time products.
  • Create a service account in Google Cloud with the Google Play Android Developer API enabled, and enter its Service account key (JSON) under the Google Play section of In-app purchase. Then invite the Service account the console shows under Users and permissions in Play Console, with two of the app's permissions: View financial data, orders, and cancellation survey responses, which the install verifies each purchase and reads refunds with, and Manage orders and subscriptions, which it consumes each purchase with. A purchase the install cannot verify does not open the episode the reader paid for, and one it cannot consume is refunded by Google after three days.

Turn on Use the App Store and Use Google Play, choose In-app purchase as how the app sells episodes, and choose Save the in-app purchase settings. The console allows that choice only once a store is ready: turned on, with its key, and with its app named under App links.

The server reference describes how a purchase is verified with each store and how refunds are applied.

Testing a purchase

Test in-app purchase with the stores' own test buyers: a sandbox account on an iPhone running a TestFlight build, and a license tester on an Android phone with a build from a testing track. Neither is charged. The install records such a purchase as a test: it opens the episode, and it is left out of royalty statements and the content statistics.

Sign in with Apple and Google

Integrations › Sign-in offers Apple and Google to readers of the site and the app at once, and Sign-in with Apple and Google covers setting it up for the site. The app offers a provider only when the tenant offers it — Offer Sign in with Apple or Offer Sign in with Google is on and complete — and only where the setup covers the phone the app runs on:

AppleGoogle
iOSWhen the app's bundle ID is the one named under App linksWhen the console's iOS client ID is the client the app was built with, and only beside Apple, as the App Store requires
AndroidWhen a Services ID is entered and the app's application ID is the one named under App linksWhen a Web client ID is entered

The same rule decides which providers Linked accounts in the app offers to link to a signed-in reader's account.

iOS

Sign in with Apple needs no Services ID in the iOS app: the console's Team ID, Key ID, and Private key (.p8) are enough, with the bundle ID from App links. The app's bundle ID is registered with the Sign in with Apple capability by Xcode when it builds.

Google sign-in on iOS needs an OAuth client of type iOS in the Google Cloud console, created with the manifest's ios.bundleIdentifier. Its client ID goes in two places, which have to agree:

  • ios.googleSignInClientId in the manifest, which registers the client with the app when it is built.
  • The iOS client ID under Integrations › Sign-in › Google, which tells the app the tenant offers it.

A change to the client therefore takes a new build as well as a change in the console.

Android

Sign in with Apple on Android signs in through Apple's web flow, under the tenant's Services ID. Register the Android app callback URL the console shows under the Return URLs of that Services ID, beside the site's own callback URL.

Google sign-in on Android uses the Web client ID the site signs in with. In the same Google Cloud project, also create an OAuth client of type Android, with the manifest's android.applicationId and the SHA-1 fingerprint of the app signing key, which Play Console shows beside the SHA-256 one on the app's App signing page. Google uses it to recognise the app; nothing in Publira names it. Google matches the client against the exact certificate the installed app is signed with, so the release APK installed for testing, which the upload key signs, needs a second Android client with the upload key's SHA-1, the SHA1: line of the keytool -list -v command on the App links page. Without it, test Google sign-in with a build installed from a Play testing track.

Sign in with a passkey

A passkey belongs to the tenant's host rather than to the browser or the app that made it, so a reader who added one on the site signs in to the app with it, and one added in the app signs in to the site. The app offers Sign in with a passkey on its sign-in screen, and Passkeys under Account, where a reader lists, adds, renames, and removes them as they do under Settings › Security on the site. A reader whose account has no password confirms Delete account and Change email address with Confirm with a passkey, above Confirm with Apple and Confirm with Google, so an account whose only other way in is a provider the phone does not offer, or that has no provider linked at all, can still do both from the app.

There is nothing to turn on: passkeys need only the apps named under App links, whose files the site serves vouch for the app's use of its passkeys. The app offers them only where it is the app named there for the phone it runs on, because the phone refuses any other the site's passkeys:

  • On iOS, the store build claims the tenant host for passkeys from the manifest's tenant.host when it is built, next to the links it claims, and is named under App links by its bundle ID and Team ID.
  • On Android, the server takes a passkey from the app only under a signing certificate whose fingerprint is saved under App links. The release APK installed for testing is signed with the upload key, so list the upload key's fingerprint as well to try passkeys with it, or test with a build installed from a Play testing track.

A build under another identity, such as the development build with its .dev identifiers, offers no passkey. The reader's phone needs a screen lock, and on Android version 9 or later with Google Play services.

Next: Submitting to the stores.