bestys-mobile/lumen-purchases

Lumen 开票验证器,适用于 Apple 和 Google Play

v0.1.0 2021-01-06 12:44 UTC

This package is auto-updated.

Last update: 2024-09-06 20:55:11 UTC


README

Laravel In-app Purchase cover

Packagist PHP Version Support Latest Version on Packagist Total Downloads GitHub last commit

✅ App Store ✅ Google Play

Laravel In-App 购买

Google Play 和 App Store 提供了 In-App Purchase (IAP) 服务。IAP 可以用来销售各种内容,包括订阅、新功能和服务等。购买事件和支付过程在移动应用(iOS 和 Android)上发生,并由移动应用处理,然后您的后端需要了解此购买事件以提供购买的产品或更新用户的订阅状态。

Laravel In-App 购买 帮助您解析和验证购买的产品,并处理订阅的不同状态,如新订阅、自动续订、取消、过期等。

目录

安装

通过 composer 安装包

composer require imdhemy/laravel-purchases

发布配置文件

php artisan vendor:publish --provider="Bestys\Purchases\PurchaseServiceProvider" --tag="config"

配置

发布的配置文件 config/purchase.php 看起来像

return [
    'routing' => [],

    'google_play_package_name' => env('GOOGLE_PLAY_PACKAGE_NAME', 'com.example.name'),

    'appstore_sandbox' => env('APPSTORE_SANDBOX', true),

    '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 Bestys\Purchases\Events\GooglePlay\SubscriptionRenewed;

class AutoRenewSubscription 
{   
    /**
    * @param SubscriptionRenewed $event
    */
    public function handle(SubscriptionRenewed $event)
    {
        // do some stuff
    }   
}

将创建的监听器添加到相关的事件键。

    // ..
        SubscriptionRenewed::class => [AutoRenewSubscription::class],
    // ..

所有事件都扩展了 \Bestys\Purchases\Events\PurchaseEvent 抽象类,该类实现了 \Bestys\Purchases\Contracts\PurchaseEventContract 接口。有关更多信息,请参阅 购买事件部分

二、Google Play 配置

以下配置特定于 Google Play

二、1 Google 应用凭据

对 Google Play 开发者 API 的请求需要身份验证和范围。要验证您的机器,请创建一个服务帐户,然后将下载的 JSON 文件 google-app-credentials.json 上传到您的服务器,最后将 GOOGLE_APPLICATION_CREDENTIALS 键添加到您的 .env 文件中,并将其设置为 JSON 文件的路径。

  1. 在云控制台中,转到 创建服务帐户密钥 页面。
  2. 服务帐户 列表中选择 新建服务帐户
  3. 服务帐户名称 字段中输入一个名称。
  4. 角色列表中选择项目 > 所有者
  5. 点击创建。一个包含您下载密钥的JSON文件将被下载到您的计算机上。
  6. 将JSON文件上传到您的存储目录或其他受保护目录。
  7. .envGOOGLE_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 产品

您可以使用\Bestys\Purchases\Facades\Product外观来确认或获取以下Google Play的收据数据:

use \Bestys\Purchases\Facades\Product;
use \Bestys\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值。更多信息请查看

  1. Google开发者文档.
  2. PHP Google Play计费包.

App Store 产品

您可以使用\Bestys\Purchases\Facades\Product向App Store发送verifyReceipt请求,如下所示

use Bestys\AppStore\Receipts\ReceiptResponse;
use \Bestys\Purchases\Facades\Product;

$receiptData = 'the_base64_encoded_receipt_data';
/** @var ReceiptResponse $receiptResponse */
$receiptResponse = Product::appStore()->receiptData($receiptData)->verifyReceipt();

像往常一样,每个键都有一个getter方法。

更多信息请查看

  1. App Store文档
  2. PHP App Store IAP包

销售订阅

Google Play 订阅

您可以使用\Bestys\Purchases\Facades\Subscription外观来确认或获取以下Google Play的收据数据:

use Bestys\GooglePlay\Subscriptions\SubscriptionPurchase;
use Bestys\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表示

更多信息请查看

  1. Google开发者文档.
  2. PHP Google Play计费包.

App Store 订阅

您可以使用\Bestys\Purchases\Facades\Subscription向App Store发送verifyReceipt请求,如下所示

use Bestys\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();

更多信息请查看

  1. 使用App Store验证收据
  2. PHP App Store IAP包

购买事件

如配置部分所述,您的应用程序应该处理订阅生命周期的不同状态。每次状态更新都会触发一个指定的事件。您可以为每种情况创建一个事件监听器来更新您的后端。

所有触发的事件都实现了Bestys\Purchases\Contracts\PurchaseEventContract接口,这使得您可以通过getServerNotification()方法获取接收通知的标准表示。

检索到的通知是类型为\Bestys\Purchases\Contracts\ServerNotificationContract,它允许您使用getSubscription()方法获取订阅的标准表示。

订阅对象提供了以下方法

  1. getExpiryTime()返回一个Time对象,告诉订阅的过期时间。
  2. getItemId()返回购买订阅的ID。
  3. getProvider()返回此订阅的提供者,即google_playapp_store
  4. getUniqueIdentifier()返回此订阅的唯一标识符。
  5. getProviderRepresentation()根据提供者返回SubscriptionPurchaseReceiptResponse

以下是一个自动续订订阅的示例

use Bestys\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);
    }   
}

测试

TODO:添加测试示例。