jinseokoh/purchase-webhooks

处理应用购买服务器端到服务器端 Webhooks

0.2.7 2021-05-25 00:12 UTC

This package is auto-updated.

Last update: 2024-09-25 08:09:11 UTC


README

背景

在编写此 API 服务器的新移动应用程序时,我发现这个 aporat/store-receipt-validator 软件包非常有用,可以验证来自苹果应用商店和谷歌应用商店的应用内购买响应。但是,有时任何人都可以直接向商店申请退款,而不通知我们取消订单。我们可能会让他们免费使用应用程序。

我知道存在可以用来检索已取消购买信息的谷歌应用商店 API。但,那不是那么2021了。这两个平台都允许我们注册 webhook URL 地址,以便发布包括初始购买和取消在内的所有商店事件。只要你有设置好 webhook,你就可以在有人退款的情况下获得几乎实时的服务器端到服务器端的通知。这意味着你可以根据自己的意愿剥夺用户在应用程序中的任何权限。

此软件包通过 Laravel Jobs 处理服务器到服务器的通知。请注意,由于超出了我的用例,订阅支付通知尚未完全支持。如果你的应用程序有基于订阅的支付选项,这可能不是你想要的。

安装

您可以通过 composer 安装此软件包

composer require jinseokoh/purchase-webhooks 

您必须使用以下命令发布配置文件

php artisan vendor:publish --provider="JinseokOh\PurchaseWebhooks\PurchaseWebhooksServiceProvider" --tag="config" 

这是将发布的配置。

<?php

return [
    // apple
    'appstore_sandbox' => (bool) env('APPLE_IAP_SANDBOX', true),
    'appstore_password' => env('APPLE_SHARED_SECRET'),

    // google
    'play_package_name' => env('GOOGLE_PLAY_PACKAGE_NAME', 'com.what.ever'),

    /*
     * Uncomment the events that should be handeled by your application.
     *
     * as for the apple app store server notifications, refer the following docs
     * https://developer.apple.com/documentation/storekit/in-app_purchase/enabling_server-to-server_notifications
     * as for the google play store server notifications, refer the following docs
     * https://developer.android.com.cn/google/play/billing/rtdn-reference
     */

    'jobs' => [
        // 'CANCEL' => \App\Jobs\Apple\WebhookCancel::class,
        // 'DID_CHANGE_RENEWAL_PREF' => \App\Jobs\Apple\WebhookDidChangeRenewalPref::class,
        // 'DID_CHANGE_RENEWAL_STATUS' => \App\Jobs\Apple\WebhookDidChangeRenewalStatus::class,
        // 'DID_FAIL_TO_RENEW' => \App\Jobs\Apple\WebhookDidFailToRenew::class,
        // 'DID_RECOVER' => \App\Jobs\Apple\WebhookDidRecover::class,
        // 'DID_RENEW' => \App\Jobs\Apple\WebhookDidRenew::class,
        // 'INITIAL_BUY' => \App\Jobs\Apple\WebhookInitialBuy::class,
        // 'INTERACTIVE_RENEWAL' => \App\Jobs\Apple\WebhookInteractiveRenewal::class,
        // 'PRICE_INCREASE_CONSENT' => \App\Jobs\Apple\WebhookPriceIncreaseConsent::class,
        // 'REFUND' => \App\Jobs\Apple\WebhookRefund::class,

        // 'ONE_TIME_PRODUCT_PURCHASED' => \App\Jobs\Google\WebhookOneTimeProductPurchased::class,
        // 'ONE_TIME_PRODUCT_CANCELED' => \App\Jobs\Google\WebhookOneTimeProductCanceled::class,
        // 'SUBSCRIPTION_RECOVERED' => \App\Jobs\Google\WebhookRecovered::class,
        // 'SUBSCRIPTION_RENEWED' => \App\Jobs\Google\WebhookRenewed::class,
        // 'SUBSCRIPTION_CANCELED' =>  \App\Jobs\Google\WebhookCanceled::class,
        // 'SUBSCRIPTION_PURCHASED' => \App\Jobs\Google\WebhookPurchased::class,
        // 'SUBSCRIPTION_ON_HOLD' => \App\Jobs\Google\WebhookOnHold::class,
        // 'SUBSCRIPTION_IN_GRACE_PERIOD' => \App\Jobs\Google\WebhookInGracePeriod::class,
        // 'SUBSCRIPTION_RESTARTED' => \App\Jobs\Google\WebhookRestarted::class,
        // 'SUBSCRIPTION_PRICE_CHANGE_CONFIRMED' => \App\Jobs\Google\WebhookPriceChangeConfirmed::class,
        // 'SUBSCRIPTION_DEFERRED' => \App\Jobs\Google\WebhookDeferred::class,
        // 'SUBSCRIPTION_PAUSED' => \App\Jobs\Google\WebhookPaused::class,
        // 'SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED' => \App\Jobs\Google\WebhookPauseScheduleChanged::class,
        // 'SUBSCRIPTION_REVOKED' => \App\Jobs\Google\WebhookRevoked::class,
        // 'SUBSCRIPTION_EXPIRED' => \App\Jobs\Google\WebhookExpired::class
    ],
];

此软件包注册以下 POST 路由

  • /webhooks/apple/purchase
  • /webhooks/google/purchase

使用方法

config/purchase.php 中取消注释您感兴趣的事件,并让每个作业类处理来自苹果/谷歌服务器的有效载荷。

处理苹果服务器通知的 Laravel 作业示例。

<?php

namespace App\Jobs\Apple;

use App\Events\VoidProductPurchase;
use App\Handlers\OrderHandler;
use JinseokOh\PurchaseWebhooks\ServerNotifications\Apple\ReceiptResponse;

class WebhookRefund
{
    private ReceiptResponse $response;
    private OrderHandler $orderHandler;

    public function __construct(
        ReceiptResponse $response,
        OrderHandler $orderHandler
    ) {
        $this->response = $response;
        $this->orderHandler = $orderHandler;
    }

    public function handle()
    {
        foreach ($this->response->getLatestReceiptInfo() as $receiptInfo) {
            $transactionId = $receiptInfo->getTransactionId();
            $order = $this->orderHandler->findByPurchaseToken($transactionId);
            if ($order) {
                event(new VoidProductPurchase($order));
            }
        }
    }
}

处理谷歌服务器通知的 Laravel 作业示例。

<?php

namespace App\Jobs\Google;

use App\Events\VoidProductPurchase;
use App\Handlers\OrderHandler;

class WebhookOneTimeProductCanceled
{
    private string $purchaseToken;
    private string $sku;
    private OrderHandler $orderHandler;

    public function __construct(
        string $purchaseToken,
        string $sku,
        OrderHandler $orderHandler
    ) {
        $this->purchaseToken = $purchaseToken;
        $this->sku = $sku;
        $this->orderHandler = $orderHandler;
    }

    public function handle()
    {
        $order = $this->orderHandler
            ->findByPurchaseToken($this->purchaseToken);
        if ($order) {
            event(new VoidProductPurchase($order));
        }
    }
}

致谢

此软件包大量基于 app-vise/laravel-appstore-notificationsimdhemy/laravel-in-app-purchases。非常感谢这些优秀软件包的作者。

许可证

MIT 许可证 (MIT)。有关更多信息,请参阅 许可证文件