ホームページ >バックエンド開発 >PHPチュートリアル >Paypalに継続控除(サブスクリプション)機能を実装する方法

Paypalに継続控除(サブスクリプション)機能を実装する方法

墨辰丷
墨辰丷オリジナル
2018-05-24 16:18:482104ブラウズ

この記事では主に、Paypal の定期的な控除 (サブスクリプション) を実装するためのアイデアと方法を紹介します。また、Paypal の支払いインターフェースの使用方法についてもまとめており、参考になります。

原因

企業は定期控除機能を実現するために Paypal を統合する必要がありましたが、Baidu と GOOGLE を探し回ったところ、Paypal の公式 Web サイト以外に関連する開発チュートリアルが見つかりませんでした。統合は成功しました。Paypal の支払いインターフェースの使用方法をまとめます。

Paypal には複数のソケットが追加されました:

  • Braintree を介してエクスプレス チェックアウトを実装します (Braintree については後で説明します)。

  • REST API インターフェース メソッド (現在の主流のインターフェース メソッド) を介してアプリを作成します。

  • NVP/SOAP API アプリのインターフェース (古いインターフェース);
Braintree のインターフェース

Braintree は、Paypal 支払いをサポートすることに加えて、アップグレード プラン、クレジット カード、顧客サービスも提供しています。情報 管理の完全なセットを待っていると、より使いやすくなります。Paypal の 2 番目の REST インターフェイスには、実際にはこれらの機能のほとんどが統合されていますが、Paypal のダッシュボードではこの情報を直接管理できませんが、Braintree では管理できるため、私は実際には Braintree を使用することを好みます。重要なのは、私が使用しているバックエンド フレームワークが Laravel であり、そのキャッシャー ソリューションがデフォルトで Braintee をサポートしているため、この一連のインターフェイスが私の第一選択であるということです。しかし、すべての機能を実装してみると、Braintree は中国ではサポートされていないという厄介な問題が見つかりました。 。 。 。 。 。死。 。 。

REST API

これは、OAuth 2.0 と REST API を以前に使用したことがある場合、これらのインターフェイスを見て混乱することはないと思います。

古いインターフェース

ポリシー制限などREST APIインターフェースを満たせない場合を除き、使用することはお勧めできません。世界中が OAuth 2.0 認証方法と REST API API の使用方法に移行しつつあるのに、なぜこの傾向に逆らうのでしょうか?したがって、REST API で問題を解決できる場合、この一連のインターフェイスの詳細な比較は行いませんでした。

REST API の概要

公式 API リファレンス ドキュメント https://developer.paypal.com/webapps/developer/docs/api/ には、その API と使用法についてのより詳細な概要が記載されていますが、それを直接調整する場合は、これらの API は依然として非常に面倒ですが、同時に、私たちは API を深く理解することにこだわるのではなく、ビジネス要件をできるだけ早く完了したいと考えています。

では、どうやって始めればよいでしょうか? 公式に提供されている PayPal-PHP-SDK を直接インストールし、その Wiki を出発点として使用することをお勧めします。

最初の例を完了する前に、サンドボックス アカウントをお持ちであることを確認し、正しく構成してください:

    クライアント ID
  • クライアント シークレット
  • Webhook API (https で始まりポート 443、ローカルである必要があります)デバッグの提案は、ngrok リバース プロキシと組み合わせてアドレスを生成します)
  • Returnurl (注記は上記と同じです)
  • Wiki の最初の例を完了した後、インターフェイスの分類を理解すると、ビジネス ニーズを完了するのに役立ちます以下にインターフェースの分類について説明します。 http://paypal.github.io/PayPal-PHP-SDK/sample/#payments を例とともに理解してください。

  • お支払い 1 回限りの支払いインターフェースでは、定期的な寄付はサポートされていません。主な支払いコンテンツには、Paypal 支払い、クレジット カード支払い、保存されたクレジット カードによるサポート (Vault インターフェイスの使用が必要です。このようなインターフェイスは主に PCI 要件によるものであり、一般的な Web サイトでは機密性の高いクレジット カード情報を収集することは許可されていません)、第三者の受取人への支払いをサポートします。

  • 支払い使用されません、無視してください

  • 承認と取得Paypalアカウントを通じてウェブサイトに直接ログインし、関連情報を取得することをサポートします。

  • セール モールに関連、未使用、無視;

  • 注文 モールに関連、未使用、無視;

  • 料金プランと契約 アップグレードプランと契約、つまりサブスクリプション関数、この記事の焦点である定期的な控除を実現するには、ここで関数を使用する必要があります

  • Vault クレジット カード情報を保存します

  • 使用されません、無視します;

  • 通知
  • 処理 Webhook 情報、重要ですが、この記事の焦点では​​ありません

  • 請求書処理、
  • 認証処理、OAuth 2 の実装。 .0にログインして入手します。他の API をリクエストするための対応するトークン。この Paypal-PHP-SDK はすでに実装されているため、この記事では説明しません。

    定期控除の実装方法

  • 4 つのステップ:

    アップグレード プランを作成して有効化します

  • サブスクリプションを作成し(契約を作成)、PaypalのWebサイトに移動してユーザーの同意を待ちます

  • ユーザーが同意したら、サブスクリプションを実行します

  • デビット請求書を取得します

  • 1. アップグレード プランの作成

    アップグレード プランは Plan クラスに対応します。このステップでは、いくつかの注意点があります:

    • アップグレード プランの作成後、プランは CREATED 状態になるため、通常に使用する前に ACTIVE に変更する必要があります。

    • プランには PaymentDefinition と MerchantPreferences という 2 つのオブジェクトがあり、どちらも空にすることはできません。

    • TRIAL タイプのプランを作成する場合は、プランに一致する REGULAR 支払い定義も必要です。そうでない場合は、エラーが発生します。報告されました;

    • コードを見ると、setSetupFee (非常に、非常に、非常に重要) メソッドが呼び出され、サブスクリプション完了後の最初の控除の料金が設定されますが、Agreement オブジェクトの循環控除メソッドは、 2回目の開始時の料金。

    標準プランの作成を例に挙げます。そのパラメータは次のとおりです:

    $param = [
     "name" => "standard_monthly",
     "display_name" => "Standard Plan",
     "desc" => "standard Plan for one month",
     "type" => "REGULAR",
     "frequency" => "MONTH",
     "frequency_interval" => 1,
     "cycles" => 0,
     "amount" => 20,
     "currency" => "USD"
     ];

    プランを作成してアクティブ化するコードは次のとおりです:

     //上面的$param例子是个数组,我的实际应用传入的实际是个对象,用户理解下就好。
     public function createPlan($param)
     {
     $apiContext = $this->getApiContext();
     $plan = new Plan();
     // # Basic Information
     // Fill up the basic information that is required for the plan
     $plan->setName($param->name)
     ->setDescription($param->desc)
     ->setType('INFINITE');//例子总是设置为无限循环
     // # Payment definitions for this billing plan.
     $paymentDefinition = new PaymentDefinition();
     // The possible values for such setters are mentioned in the setter method documentation.
     // Just open the class file. e.g. lib/PayPal/Api/PaymentDefinition.php and look for setFrequency method.
     // You should be able to see the acceptable values in the comments.
     $paymentDefinition->setName($param->name)
     ->setType($param->type)
     ->setFrequency($param->frequency)
     ->setFrequencyInterval((string)$param->frequency_interval)
     ->setCycles((string)$param->cycles)
     ->setAmount(new Currency(array('value' => $param->amount, 'currency' => $param->currency)));
     // Charge Models
     $chargeModel = new ChargeModel();
     $chargeModel->setType('TAX')
     ->setAmount(new Currency(array('value' => 0, 'currency' => $param->currency)));
     $returnUrl = config('payment.returnurl');
     $merchantPreferences = new MerchantPreferences();
     $merchantPreferences->setReturnUrl("$returnUrl?success=true")
     ->setCancelUrl("$returnUrl?success=false")
     ->setAutoBillAmount("yes")
     ->setInitialFailAmountAction("CONTINUE")
     ->setMaxFailAttempts("0")
     ->setSetupFee(new Currency(array('value' => $param->amount, 'currency' => 'USD')));
     $plan->setPaymentDefinitions(array($paymentDefinition));
     $plan->setMerchantPreferences($merchantPreferences);
     // For Sample Purposes Only.
     $request = clone $plan;
     // ### Create Plan
     try {
     $output = $plan->create($apiContext);
     } catch (Exception $ex) {
     return false;
     }
     $patch = new Patch();
     $value = new PayPalModel('{"state":"ACTIVE"}');
     $patch->setOp('replace')
     ->setPath('/')
     ->setValue($value);
     $patchRequest = new PatchRequest();
     $patchRequest->addPatch($patch);
     $output->update($patchRequest, $apiContext);
     return $output;
     }

    2. 作成します。サブスクリプション (契約の作成) を実行し、Paypal の Web サイトに移動してユーザーの同意を待ちます

    プランの作成後、実際にユーザーに契約を作成させるにはどうすればよいですか?同意するには、次の点に注意する必要があります。

    • 前述したように、Plan オブジェクトの setSetupFee メソッドはサブスクリプション完了後の最初の控除の料金を設定し、Agreement オブジェクトの循環控除メソッドは 2 回目の控除の料金を設定します。 2回目のスタート。

    • setStartDate メソッドは 2 番目の控除の時間を設定するため、月単位でサイクルする場合は、現在の時間に 1 か月を加えたものにする必要があります。同時に、このメソッドでは時間形式が ISO8601 形式である必要があります。これは、Carbon ライブラリを使用して簡単に解決できます。

    • 契約を作成するとき、一意の ID がまだ生成されていなかったため、少し問題に遭遇しました。ユーザーがサブスクリプションを完了したときに、どのユーザーがサブスクリプションを持っているかをどうやって知るかです。属する?アグリーメントの getApprovalLink メソッドを通じて取得された URL 内のトークンは一意であり、ユーザーがサブスクリプションを完了した後、識別方法としてトークンを抽出し、実際の ID に置き換えます。

    パラメータの例は次のとおりです:

    $param = [
     'id' => 'P-26T36113JT475352643KGIHY',//上一步创建Plan时生成的ID
     'name' => 'Standard', 
     'desc' => 'Standard Plan for one month'
    ];

    コードは次のとおりです:

     public function createPayment($param)
     {
     $apiContext = $this->getApiContext();
     $agreement = new Agreement();
     $agreement->setName($param['name'])
     ->setDescription($param['desc'])
     ->setStartDate(Carbon::now()->addMonths(1)->toIso8601String());
     // Add Plan ID
     // Please note that the plan Id should be only set in this case.
     $plan = new Plan();
     $plan->setId($param['id']);
     $agreement->setPlan($plan);
     // Add Payer
     $payer = new Payer();
     $payer->setPaymentMethod('paypal');
     $agreement->setPayer($payer);
     // For Sample Purposes Only.
     $request = clone $agreement;
     // ### Create Agreement
     try {
     // Please note that as the agreement has not yet activated, we wont be receiving the ID just yet.
     $agreement = $agreement->create($apiContext);
     // ### Get redirect url
     // The API response provides the url that you must redirect
     // the buyer to. Retrieve the url from the $agreement->getApprovalLink()
     // method
     $approvalUrl = $agreement->getApprovalLink();
     } catch (Exception $ex) {
     return "create payment failed, please retry or contact the merchant.";
     }
     return $approvalUrl;//跳转到$approvalUrl,等待用户同意
     }

    関数が実行された後、$approvalUrl を介して Paypal Web サイトにジャンプすることを忘れないでください。 redirect($approvalUrl) してユーザーの支払いを待ちます。

    ユーザーが同意したら、サブスクリプションを実行します

    ユーザーが同意した後、サブスクリプションは完了していませんので、実際のサブスクリプションを完了するには、Agreementのexecuteメソッドを実行する必要があります。このステップで注意すべき重要な点は、

    • サブスクリプションの完了後、支払いが差し引かれるわけではなく、数分間遅れる可能性があることです。

    • 最初の setSetupFee 料金がstep が 0 に設定されている場合は、定期控除時間が経過するまで待つ必要があります

    コード スニペットは次のとおりです:

     public function onPay($request)
     {
     $apiContext = $this->getApiContext();
     if ($request->has('success') && $request->success == 'true') {
     $token = $request->token;
     $agreement = new \PayPal\Api\Agreement();
     try {
     $agreement->execute($token, $apiContext);
     } catch(\Exception $e) {
     return ull;
     return $agreement;
     }
     return null;
     }

    After登録すると、取引控除の取引記録がすぐに生成されない場合があります。空の場合は、再試行するのに数秒かかります。このステップに関する注意事項:

    start_date と end_date を空にすることはできません

    • 実際のテスト中、この関数によって返されるオブジェクトは常に空の JSON オブジェクトを返すとは限らないため、JSON を出力する必要がある場合は API の手順に従ってください。 ContractTransactions の場合は、対応するパラメータを手動で抽出します。

    •  /** 获取交易记录
       * @param $id subscription payment_id
       * @warning 总是获取该subscription的所有记录
       */
       public function transactions($id)
       {
       $apiContext = $this->getApiContext();
       $params = ['start_date' => date('Y-m-d', strtotime('-15 years')), 'end_date' => date('Y-m-d', strtotime('+5 days'))];
       try {
       $result = Agreement::searchTransactions($id, $params, $apiContext);
       } catch(\Exception $e) {
       Log::error("get transactions failed" . $e->getMessage());
       return null;
       }
       return $result->getAgreementTransactionList() ;
       }

    最後に、もちろん Paypal にも対応する公式チュートリアルがありますが、ネイティブ インターフェイスを呼び出します。上記のプロセスとの違いは、最初の 3 つのステップについてのみ説明していることです。参考までに: https :/ /developer.paypal.com/docs/integration/direct/billing-plans-and-agreements/。

    考慮すべき点

    機能は実装されましたが、注意すべき点も多く見つかりました

    中国でサンドボックステストを使用すると特に接続が遅く、タイムアウトが頻繁に発生しますページの状況

    • 必ず Webhook を実装してください。そうしないと、ユーザーが Paypal を通じてサブスクリプションをキャンセルしたときに Web サイトに通知されません。 ;

    • サブスクリプション (契約) は一度生成されると、積極的にキャンセルされない限り有効になります。したがって、Web サイトが複数のアップグレード プラン (ベーシック、スタンダード、アドバンスなど) で設計されている場合、ユーザーが特定のプランに加入してアップグレード プランに切り替えると、開発者は以前のアップグレード プランをキャンセルする必要があります

    • 。ユーザーがサブスクリプションに同意する - (古いサブスクリプションをキャンセルする - 新しいサブスクリプションの署名を完了する - 新しいサブスクリプションにユーザー情報を変更する)、括弧のプロセス全体はアトミックな操作である必要があり、長い時間がかかるため、次のようにする必要があります。成功するまで実行のキューに入れられ、エクスペリエンスが向上します。

    • 以上がこの記事の全内容です、皆様の学習のお役に立てれば幸いです。

    関連おすすめ:

    Paypal定期控除(サブスクリプション)機能を実装するサンプルコードを共有します

    Paypalで予約した電話番号を注文に追加するzenカートメソッド

    paypalの最もシンプルなPHPオンライン決済SDK

以上がPaypalに継続控除(サブスクリプション)機能を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。