Apple App Store
Poskytovateľ Apple (id apple) overuje podpísané serverové notifikácie App Store — ES256 JWS, ktorého reťazec certifikátov x5c je pripnutý na zverejnené certifikáty Apple — a dekóduje vnorené podpísané údaje o transakcii a obnovení:
use RoundlyConsulting\Purchases\Providers\Apple\Apple;
// Verify a signed App Store server notification (ES256 JWS, native).
$payload = app(Apple::class)->notification($request); // reads the signedPayload field
$payload->type; // NotificationType, e.g. TypeDidRenew
$payload->subType; // ?NotificationSubType (null for REFUND, REVOKE, TEST …)
$payload->transactionInfo?->productId;
$payload->transactionInfo?->originalTransactionId;
$payload->transactionInfo?->expiresDate; // ?Carbon
$payload->renewalInfo; // ?RenewalInfoLen vaša aplikácia
Apple podpisuje notifikácie všetkých aplikácií tým istým reťazcom certifikátov, takže pravý podpis dokazuje len to, že notifikáciu poslal Apple — nie že sa týka vašej aplikácie. notification() (a teda aj result(), handle() a webhook routa) preto navyše vyžaduje, aby notifikácia — a každá transakcia a obnova, ktorú nesie — uvádzala váš PURCHASES_APPLE_BUNDLE_ID a vaše prostredie (PURCHASES_APPLE_SANDBOX), v produkcii aj váš PURCHASES_APPLE_APP_APPLE_ID. Čokoľvek iné vyhodí VerificationException (routa vráti 400); bez nastaveného bundle id sa odmietne každá notifikácia. Rovnako sa viaže aj transakcia načítaná cez AppStoreServerApi::transaction():
PURCHASES_APPLE_BUNDLE_ID=com.example.app
PURCHASES_APPLE_APP_APPLE_ID=1234567890
PURCHASES_APPLE_SANDBOX=false # the default; true on a host that receives Sandbox notificationsApp Store Server API
Po nastavení prístupových údajov api.* komunikuje AppStoreServerApi s moderným API Apple — preferovanou cestou oproti zastaranému verifyReceipt. transaction() načíta a overí podpísanú transakciu; requestTestNotification() požiada Apple o testovaciu notifikáciu a využíva ju purchases:verify:
use RoundlyConsulting\Purchases\Providers\Apple\AppStoreServerApi;
$api = app(AppStoreServerApi::class);
// Modern App Store Server API (preferred over the deprecated verifyReceipt path).
$transaction = $api->transaction('2000000000000001'); // TransactionInfo, JWS verified
$transaction->productId;
$transaction->purchaseDate; // ?Carbon
$transaction->price; // ?int — milli-units
$transaction->currency; // ?string
$api->requestTestNotification(); // asks Apple to send a test notificationMapovanie notifikácií Apple
| Notifikácia Apple | Stav |
|---|---|
| SUBSCRIBED, DID_RENEW, OFFER_REDEEMED, ONE_TIME_CHARGE, REFUND_REVERSED, RENEWAL_EXTENDED, okamžitý UPGRADE | Completed |
| DID_FAIL_TO_RENEW s podtypom GRACE_PERIOD | InGracePeriod |
| DID_FAIL_TO_RENEW bez neho (opakovanie platby), GRACE_PERIOD_EXPIRED | OnHold |
| EXPIRED | Failed |
| REFUND, REVOKE (výsledok typu Refund) | Refunded |
| Zmena preferencie alebo stavu obnovy, zvýšenie či zmena ceny, žiadosť o spotrebe, REFUND_DECLINED, TEST a neznáme typy | Informatívne — len audit, nikdy sa neuplatní |
Notifikácia s transakciou je kľúčovaná podľa originalTransactionId, ako názov nesie identifikátor produktu a ako endsAt dátum expiresDate transakcie. Cena pochádza z podpísanej transakcie v tisícinách a zaokrúhľuje sa od nuly na najmenšiu jednotku meny.
Staršie účtenky
Apple::callback() stále posiela surové telo požiadavky na zastaraný endpoint verifyReceipt spolu so zdieľaným kľúčom zo settings.apple.password a vracia ReceiptResponse — ak Apple označí účtenku za neplatnú, vyhodí VerificationException. V novom kóde uprednostnite App Store Server API.
Platnosť certifikátov a toleranciu posunu hodín opisuje sekcia Overovanie podpisov a dôvera.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.