trunk-studio/ laravel-in-app-purchases
Laravel Google Play收据验证器
Requires
- php: >=7.1
- ext-json: *
- imdhemy/appstore-iap: ^0.3
- imdhemy/google-play-billing: ^0.6
- nesbot/carbon: ^2.41
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.17
- orchestra/testbench: ^5.0
- phpunit/phpunit: ^8.5
- psalm/plugin-laravel: ^1.2
- vimeo/psalm: ^4.3
This package is auto-updated.
Last update: 2024-09-19 11:31:08 UTC
README
✅ App Store ✅ Google Play
Laravel 内购
Google Play 和 App Store 提供内购(IAP)服务。IAP 可用于销售各种内容,包括订阅、新功能和服务等。购买事件和支付流程在移动应用程序(iOS 和 Android)上发生并处理,然后您的后端需要了解此购买事件以交付购买的产品或更新用户的订阅状态。
Laravel 内购可帮助您解析和验证购买的产品,并处理订阅的不同状态,如新订阅、自动续订、取消、过期等。
目录
安装
通过 composer 安装包
composer require imdhemy/laravel-purchases
发布配置文件
php artisan vendor:publish --provider="Imdhemy\Purchases\PurchaseServiceProvider" --tag="config"
配置
发布的配置文件 config/purchase.php 如下所示
return [ 'routing' => [], 'google_play_package_name' => env('GOOGLE_PLAY_PACKAGE_NAME', 'com.example.name'), 'appstore_password' => env('APPSTORE_PASSWORD', ''), 'eventListeners' => [ /** * -------------------------------------------------------- * Google Play Events * -------------------------------------------------------- */ SubscriptionPurchased::class => [], SubscriptionRenewed::class => [], SubscriptionInGracePeriod::class => [], SubscriptionExpired::class => [], SubscriptionCanceled::class => [], SubscriptionPaused::class => [], SubscriptionRestarted::class => [], SubscriptionDeferred::class => [], SubscriptionRevoked::class => [], SubscriptionOnHold::class => [], SubscriptionRecovered::class => [], SubscriptionPauseScheduleChanged::class => [], SubscriptionPriceChangeConfirmed::class => [], /** * -------------------------------------------------------- * Appstore Events * -------------------------------------------------------- */ Cancel::class => [], DidChangeRenewalPref::class => [], DidChangeRenewalStatus::class => [], DidFailToRenew::class => [], DidRecover::class => [], DidRenew::class => [], InitialBuy::class => [], InteractiveRenewal::class => [], PriceIncreaseConsent::class => [], Refund::class => [], ], ];
每个配置选项都在配置部分中进行了说明。
一、通用配置
通用配置不特定于两个支持提供商(Google 和 Apple)中的任何一个。
一、1 路由
此包添加了两个 POST 端点来接收实时开发者通知和App Store 服务器通知。
可以通过配置文件中的 routing 键配置这些路由。例如
[
// ..
'routing' => [
'middleware' => 'api',
'prefix' => 'my_prefix'
],
// ..
];
一、2 事件监听器
您的应用程序应处理订阅生命周期的不同状态。每个状态更新都会触发一个指定的事件。您可以为每种情况创建一个事件监听器来更新您的后端。
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionRenewed; class AutoRenewSubscription { /** * @param SubscriptionRenewed $event */ public function handle(SubscriptionRenewed $event) { // do some stuff } }
将创建的监听器添加到相关的事件键中。
// .. SubscriptionRenewed::class => [AutoRenewSubscription::class], // ..
所有事件都扩展了 \Imdhemy\Purchases\Events\PurchaseEvent 抽象类,该类实现了 \Imdhemy\Purchases\Contracts\PurchaseEventContract 接口。有关更多信息,请参阅购买事件部分。
二、Google Play 配置
以下配置特定于 Google Play
二、1 Google 应用程序凭据
请求 Google Play 开发者 API 需要身份验证和作用域。要身份验证您的机器,请创建一个服务帐户,然后将下载的 JSON 文件 google-app-credentials.json 上传到您的服务器,最后将 GOOGLE_APPLICATION_CREDENTIALS 键添加到您的 .env 文件中,并将其设置为 JSON 文件的路径。
- 在云控制台中,转到创建服务帐户密钥页面。
- 从 服务帐户 列表中,选择 新建服务帐户。
- 在 服务帐户名称 字段中,输入一个名称。
- 从 角色 列表中,选择 项目 > 所有者。
- 点击 创建。一个包含您的密钥的 JSON 文件将下载到您的计算机。
- 将 JSON 文件上传到您的存储目录或任何受保护的目录。
- 将
.env键GOOGLE_APPLICATION_CREDENTIALS设置为 JSON 文件路径。
二、2 Google Play 包名
购买此订阅的应用程序的包名(例如,'com.some.thing')。
三、App Store 配置
以下配置特定于 App Store。
三、1 App Store 沙盒
配置键 appstore_sandbox 是一个布尔值,用于确定发送到 App Store 的请求是否在沙盒中。
三、2 App Store 密码
请求 App Store 需要设置键 appstore_password。您的应用的共享密钥,是一个十六进制字符串。
销售产品
Google 产品
您可以使用 \Imdhemy\Purchases\Facades\Product 门面按照以下方式确认或获取 Google Play 的收据数据:
use \Imdhemy\Purchases\Facades\Product; use \Imdhemy\GooglePlay\Products\ProductPurchase; $itemId = 'product_id'; $token = 'purchase_token'; Product::googlePlay()->id($itemId)->token($token)->acknowledge(); // You can optionally submit a developer payload Product::googlePlay()->id($itemId)->token($token)->acknowledge("your_developer_payload"); /** @var ProductPurchase $productReceipt */ $productReceipt = Product::googlePlay()->id($itemId)->token($token)->get();
每个键都有一个以 get 为前缀的获取方法,例如:使用 getKind() 获取 kind 值。有关更多信息,请查看
App Store 产品
您可以使用 \Imdhemy\Purchases\Facades\Product 发送 verifyReceipt 请求到 App Store,如下所示
use Imdhemy\Purchases\Receipts\AppStore\ReceiptResponse; use \Imdhemy\Purchases\Facades\Product; $receiptData = 'the_base64_encoded_receipt_data'; /** @var ReceiptResponse $receiptResponse */ $receiptResponse = Product::appStore()->receiptData($receiptData)->verifyReceipt();
如往常一样,每个键都有一个获取方法。
有关更多信息,请查看
销售订阅
Google Play 订阅
您可以使用 \Imdhemy\Purchases\Facades\Subscription 门面按照以下方式确认或获取 Google Play 的收据数据:
use Imdhemy\Purchases\Receipts\GooglePlay\SubscriptionPurchase; use Imdhemy\Purchases\Facades\Subscription; $itemId = 'product_id'; $token = 'purchase_token'; Subscription::googlePlay()->id($itemId)->token($token)->acknowledge(); // You can optionally submit a developer payload Subscription::googlePlay()->id($itemId)->token($token)->acknowledge("your_developer_payload"); /** @var SubscriptionPurchase $subscriptionReceipt */ $subscriptionReceipt = Subscription::googlePlay()->id($itemId)->token($token)->get(); // You can optionally override the package name Subscription::googlePlay()->packageName('com.example.name')->id($itemId)->token($token)->get();
SubscriptionPurchase 资源表示用户内购产品购买的状态。这是其 JSON 表示形式
有关更多信息,请查看
App Store 订阅
您可以使用 \Imdhemy\Purchases\Facades\Subscription 发送 verifyReceipt 请求到 App Store,如下所示
use Imdhemy\Purchases\Facades\Subscription; // To verify a subscription receipt $receiptData = 'the_base64_encoded_receipt_data'; $receiptResponse = Subscription::appStore()->receiptData($receiptData)->verifyReceipt(); // If the subscription is an auto-renewable one, //call the renewable() method before the trigger method verifyReceipt() $receiptResponse = Subscription::appStore()->receiptData($receiptData)->renewable()->verifyReceipt(); // or you can omit the renewable() method and use the verifyRenewable() method instead $receiptResponse = Subscription::appStore()->receiptData($receiptData)->verifyRenewable();
有关更多信息,请查看
购买事件
如前所述,在 配置部分 中,您的应用程序应处理订阅生命周期的不同状态。每个状态更新都会触发一个指定的事件。您可以为每种情况创建事件监听器以更新您的后端。
所有触发的事件都实现了 Imdhemy\Purchases\Contracts\PurchaseEventContract 接口,它允许您通过 getServerNotification() 方法获取接收通知的标准表示。
检索到的通知是 \Imdhemy\Purchases\Contracts\ServerNotificationContract 类型,它允许您通过 getSubscription() 方法获取订阅的标准表示。
订阅对象提供了以下方法
getExpiryTime()返回一个Time对象,告知订阅的到期时间。getItemId()返回购买的订阅 id。getProvider()返回此订阅的提供者,可以是google_play或app_store。getUniqueIdentifier()返回此订阅的唯一标识符。getProviderRepresentation()根据提供者返回SubscriptionPurchase或ReceiptResponse。
以下是一个自动续订订阅的示例
use Imdhemy\Purchases\Events\GooglePlay\SubscriptionRenewed; class AutoRenewSubscription { /** * @param SubscriptionRenewed $event */ public function handle(SubscriptionRenewed $event) { // The following data can be retrieved from the event $notification = $event->getServerNotification(); $subscription = $notification->getSubscription(); $uniqueIdentifier = $subscription->getUniqueIdentifier(); $expirationTime = $subscription->getExpiryTime(); // The following steps are up to you, this is only an imagined scenario. $user = $this->findUserBySubscriptionId($uniqueIdentifier); $user->getSubscription()->setExpirationTime($expirationTime); $user->save(); $this->notifyUserAboutUpdate($user); } }
测试
待办事项:添加测试示例。
