定制 bestys-mobile/lumen-purchases 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

bestys-mobile/lumen-purchases

Composer 安装命令:

composer require bestys-mobile/lumen-purchases

包简介

Lumen receipt validator for Apple and Google Play

README 文档

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 purchase

Google Play and App Store provide the In-App Purchase (IAP) services. IAP can be used to sell a variety of content, including subscriptions, new features, and services. The purchase event and the payment process occurs on and handled by the mobile application (iOS and Android), then your backend needs to be informed about this purchase event to deliver the purchased product or update the user's subscription state.

Laravel In-App purchase comes to help you to parse and validate the purchased products and handle the different states of a subscription, like New subscription , auto-renew, cancellation, expiration and etc.

Table of contents

Installation

Install the package via composer:

composer require imdhemy/laravel-purchases

Publish the config file:

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

Configuration

The published config file config/purchase.php looks like:

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 => [],
    ],
];

Each configuration option is illustrated in the configuration section.

i. Generic Configurations:

The generic configurations are not specific to a particular provider of the two supported providers (Google and Apple).

i.1 Routing

This package adds two POST endpoints to receive the Real-Time Developer Notifications, and the The App Store Server Notifications.

Provider URI Name
Google Play /purchases/subscriptions/google purchase.serverNotifications.google
App Store /purchases/subscriptions/apple purchase.serverNotifications.apple

These routes can be configured through the routing key in the config file. For example:

[
    // ..
   'routing' => [
        'middleware' => 'api',
        'prefix' => 'my_prefix'
    ],
    // ..
];

i.2 Event Listeners

Your application should handle the different states of a subscription life. Each state update triggers a specified event. You can create an event listener to update your backend on each case.

use Bestys\Purchases\Events\GooglePlay\SubscriptionRenewed;

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

Add the created listener to the associated event key.

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

All events extend the \Bestys\Purchases\Events\PurchaseEvent abstract class, which implements the \Bestys\Purchases\Contracts\PurchaseEventContract interface. Check the Purchase Events section for more information.

ii. Google Play Configurations:

The following set of configurations are specific to google play:

ii.1 Google Application Credentials

Requests to the Google Play Developer API, requires authentication and scopes. To authenticate your machine create a service account, then upload the downloaded JSON file google-app-credentials.json to your server, and finally add GOOGLE_APPLICATION_CREDENTIALS key to your .env file and set it to the path of JSON file.

  1. In the Cloud Console, go to the Create service account key page.
  2. From the Service account list, select New service account.
  3. In the Service account name field, enter a name.
  4. From the Role list, select Project > Owner.
  5. Click Create. A JSON file that contains your key downloads to your computer.
  6. Upload the JSON file to your storage directory, or any other protected directory.
  7. Set the .env key GOOGLE_APPLICATION_CREDENTIALS to the JSON file path.

ii.2 Google Play Package Name

The package name of the application for which this subscription was purchased (for example, 'com.some.thing').

iii. App Store Configurations

The following set of configurations are specific to the App Store.

iii.1 App Store Sandbox

The configuration key appstore_sandbox is a boolean value that determines whether the requests sent to the App Store are in the sandbox or not.

iii.2 App Store Password

Request to the App Store requires the key appstore_password to be set. Your app’s shared secret, which is a hexadecimal string.

Sell Products

Google Products

You can use the \Bestys\Purchases\Facades\Product facade to acknowledge or to get the receipt data from Google Play as follows:

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();

Each key has a getter method prefixed with get, for example: getKind() to get the kind value. For more information check:

  1. Google Developer documentation.
  2. PHP Google Play Billing Package.

App Store Products

You can use the \Bestys\Purchases\Facades\Product to send a verifyReceipt request to the App Store. as follows:

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();

As usual each key has a getter method.

For more information check:

  1. App Store Documentation
  2. PHP App Store IAP package

Sell Subscriptions

Google Play Subscriptions

You can use the \Bestys\Purchases\Facades\Subscription facade to acknowledge or to get the receipt data from Google Play as follows:

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();

The SubscriptionPurchase resource indicates the status of a user's inapp product purchase. This is its JSON Representation:

For more information check:

  1. Google Developer documentation.
  2. PHP Google Play Billing Package.

App Store Subscriptions

You can use the \Bestys\Purchases\Facades\Subscription to send a verifyReceipt request to the App Store. as follows:

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();

For more information check:

  1. Validating Receipts with the App Store
  2. PHP App Store IAP package

Purchase Events

As mentioned the configuration section, Your application should handle the different states of a subscription life. Each state update triggers a specified event. You can create an event listener to update your backend on each case.

All triggered events implement Bestys\Purchases\Contracts\PurchaseEventContract interface, which allows you to get a standard representation of the received notification through the getServerNotification() method.

The retrieved notification is of type \Bestys\Purchases\Contracts\ServerNotificationContract which allows you to get a standard representation of the subscription using the getSubscription() method.

The subscription object provides the following methods:

  1. getExpiryTime() returns a Time object that tells the expiration time of the subscription.
  2. getItemId() returns the purchased subscription id.
  3. getProvider() returns the provider of this subscription, either google_play or app_store.
  4. getUniqueIdentifier() returns a unique identifier for this subscription.
  5. getProviderRepresentation() returns either SubscriptionPurchase or ReceiptResponse based on the provider.

Here is an example of an auto-renewed subscription:

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);
    }   
}

Testing

TODO: add testing examples.

bestys-mobile/lumen-purchases 适用场景与选型建议

bestys-mobile/lumen-purchases 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 13 次下载、GitHub Stars 达 0, 最近一次更新时间为 2021 年 01 月 06 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「lumen」 「google_play」 「in_app_purchases」 「lumen-in-app-purchases」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 bestys-mobile/lumen-purchases 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 bestys-mobile/lumen-purchases 我们能提供哪些服务?
定制开发 / 二次开发

基于 bestys-mobile/lumen-purchases 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 13
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 7
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2021-01-06