>백엔드 개발 >PHP 튜토리얼 >반복 공제(구독) 기능 구현을 위한 Paypal 샘플 코드 공유

반복 공제(구독) 기능 구현을 위한 Paypal 샘플 코드 공유

黄舟
黄舟원래의
2017-03-24 09:26:063019검색

본 글에서는 정기공제(구독)를 구현하기 위한 Paypal의 아이디어와 방법을 주로 소개하고, 참고할만한 좋은 Paypal의 결제 인터페이스 사용법도 정리했습니다. 아래 에디터로 살펴보겠습니다

원인

정기공제 기능을 실현하려면 페이팔을 통합해야 하는데 바이두와 GOOGLE이 돌아섰습니다. , 공식 웹사이트를 제외하고는 관련 개발 튜토리얼을 찾을 수 없어서 Paypal을 살펴보아야 했습니다. 이틀 후에 통합이 성공적으로 이루어졌습니다. Paypal의 결제 인터페이스 사용 방법은 다음과 같습니다.

Paypal에는 이제 여러 소켓이 있습니다.

  • Express Checkout은 Braintree를 통해 구현됩니다(Braintree에 대해서는 나중에 설명하겠습니다). >

  • REST Api 인터페이스를 통해 앱 생성(현재 주류 인터페이스);
  • NVP/SOAP API 앱 인터페이스(기존 인터페이스)
Braintree의 인터페이스

Braintree는 Paypal 결제 지원 외에도 업그레이드 플랜, 신용 카드, 고객 정보, 완전한 일련의 관리, 사용하기 더 편리합니다. Paypal의 두 번째 REST 인터페이스 세트는 실제로 이러한 기능의 대부분을 통합하지만 Paypal의 Dashboard는 이 정보를 직접 관리할 수 없지만 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를 직접 조정하는 것은 여전히 ​​매우 번거로운 일이지만, 동시에 비즈니스 요구 사항을 최대한 빨리 완료하고 싶습니다. API에 대해 깊이 이해하는 대신.

그렇다면 어떻게 시작해야 할까요? 공식적으로 제공되는 PayPal-PHP-SDK를 직접 설치하고 해당 Wiki를 시작점으로 사용하는 것이 좋습니다.

첫 번째 예를 완료하기 전에 샌드박스 계정이 있는지 확인하고 올바르게 구성하세요.

    클라이언트 ID
  • 클라이언트 시크릿
  • Webhook API(https로 시작하고 포트 443이어야 함, ngrok 역방향 프록시와 함께 주소를 생성하려면 로컬
  • 디버깅

    권장)

  • Returnurl(위와 동일)
  • 결제 일회성 결제 인터페이스는 반복 기부를 지원하지 않습니다. 주요 결제 콘텐츠에는 Paypal 결제 지원, 신용 카드 결제, 저장된 신용 카드를 통한 지원(Vault 인터페이스 사용이 필요하며 이러한 인터페이스는 주로 PCI 요구 사항으로 인해 발생하며 일반 웹사이트에서는 민감한 신용 카드 정보를 수집할 수 없습니다), 제3자 수취인에 대한 결제를 지원합니다.

  • 지급 사용하지 않음, 무시

  • Capture 는 Paypal 계정을 통해 웹사이트에 직접 로그인하고 관련 정보를 얻을 수 있도록 지원합니다.

  • 판매 쇼핑몰에, 미사용, 무시;

  • 주문 쇼핑몰 관련, 미사용, 무시;

  • 빌링 플랜 및 계약 업그레이드 플랜 및 계약, 즉 구독 기능, 반복 공제를 달성하려면 여기에서 기능을 사용해야 합니다. 이것이 이 글의 초점입니다. 기사

  • Vault신용카드 정보 저장

  • 결제 경험 사용되지 않음, 무시, 중요하지만 이 기사의 초점은 아님 송장

  • 송장 처리;
  • ID 인증 처리, OAuth 2.0 로그인 구현 및 기타 API를 요청하기 위한 해당 토큰 획득 이 Paypal-PHP-SDK에는 이미 구현되었으므로 이 문서에서는 다루지 않습니다.

  • 반복 공제 실행 방법 4단계:

  • 업그레이드 계획을 생성하고 활성화하세요. 구독을 생성한 다음(계약 생성) Paypal 웹사이트로 이동하여 사용자 승인을 기다립니다.

    사용자 동의 후 구독 실행

출금 청구서 받기

  1. 1. 계획

  2. 업그레이드 계획은 계획 클래스에 해당합니다. 이 단계에서는 몇 가지 주의할 사항이 있습니다.

    • 업그레이드 계획이 생성된 후에는 CREATED 상태이며 정상적으로 사용하려면 먼저 ACTIVE로 변경해야 합니다.

    • Plan에는 PaymentDefinition과 MerchantPreferences라는 두 개의 개체가 있으며 둘 다 비워 둘 수 없습니다.

    • TRIAL 유형 계획을 생성하려면, 계획에는 일치하는 REGULAR 지불 정의도 있어야 합니다. 그렇지 않으면 오류가 보고됩니다.

    • 코드를 보면 setSetupFee(매우, 매우, 매우 중요) 메소드가 호출됩니다. 이후 첫 번째 인출에 대한 수수료를 설정하고, 계약 개체의 반복 공제 방법은 두 번째 시작 시 수수료를 설정합니다.

    표준 계획 생성을 예로 들어 보겠습니다. 해당 매개변수는 다음과 같습니다.

    $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 웹사이트로 이동하여 사용자 동의를 기다립니다.

    계획이 생성된 후 어떻게 해야 합니까? 실제로 사용자가 계약을 생성하도록 허용하는 것입니다. 계약과 관련하여 다음 사항에 유의해야 합니다.

    • 앞서 언급한 것처럼 Plan 개체의 setSetupFee 메서드는 가입 완료 후 첫 번째 공제 수수료는 계약 대상의 순환 공제 방식으로 두 번째 시작 시 수수료가 설정됩니다.

    • setStartDate 메소드는 두 번째 공제 시간을 설정하므로 월 단위로 순환하는 경우 현재 시간에 한 달을 더해야 합니다. 시간 형식이 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을 반환합니다. 실행 후에는 사용자 결제를 기다리기 위해 리디렉션($approvalUrl)을 전달하여 Paypal 웹사이트로 이동하는 것을 기억하세요.

    이용자 동의 후 구독 실행

    이용자 동의 후 구독이 완료되지 않은 것과 계약 이행 방법 실행해야 진정한 구독이 완료됩니다. 이 단계에서 중요한 점은

    • 구독을 완료했다고 해서 결제가 차감되는 것은 아니며, 몇 분 정도 지연될 수 있다는 점입니다. >

    • 첫 번째 단계에서 setSetupFee 수수료가 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;
     }

    거래 기록 가져오기

    가입 후 거래 차감 거래 기록이 즉시 생성되지 않을 수 있습니다. 비어 있습니다. 몇 분 후에 다시 시도하세요. 이 단계에 대한 참고 사항:

    • start_date 및 end_date는 비워둘 수 없습니다

    • 실제 테스트 중에 이 함수에서 반환된 개체가 항상 비어 있는 상태를 반환할 수는 없습니다. 🎜>JSON

      객체이므로 JSON을 출력해야 하는 경우 AgreementTransactions의 API 설명에 따라 해당 매개변수를 수동으로 추출하세요.

       /** 获取交易记录
       * @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에도 해당 공식 튜토리얼이 있지만 기본 인터페이스를 호출한다는 점에서 위 프로세스와의 차이점은 처음 세 단계만 설명한다는 것입니다. >

    고려해야 할 문제

    기능이 구현되었지만 주의사항도 많이 발견되었습니다.

    특히 중국에서 테스트용으로 샌드박스를 사용하는 경우 연결 속도가 느려지므로 타임아웃이나 오류가 발생하는 경우가 많기 때문에 실행 중에 사용자가 페이지를 닫는 상황에 대해서는 특별한 주의가 필요합니다. 🎜>웹훅을 구현하세요. 그렇지 않으면 사용자가 Paypal에서 구독을 취소하면 웹사이트에서 알림을 받을 수 없습니다.
    • 구독(계약)이 생성되면, 적극적으로 취소하지 않는 한 유효하게 유지됩니다. 따라서 웹사이트가 여러 업그레이드 플랜(예: Basic, Standard, Advanced)으로 설계된 경우 사용자가 플랜을 구독하고 업그레이드 플랜으로 전환하면 개발 중에 이전 업그레이드 플랜을 취소해야 합니다.
    • 사용자가 구독에 동의함 - (기존 구독 취소 - 새 구독 서명 완료 -
    • 새 구독에 대한 사용자 정보 수정
    • ), 괄호의 전체 과정은 다음과 같습니다. 원자적인 작업이므로 시간이 많이 걸리고 시간이 오래 걸립니다. 따라서

      에 넣고 성공할 때까지 실행해야 더 나은 경험을 제공할 수 있습니다.

위 내용은 반복 공제(구독) 기능 구현을 위한 Paypal 샘플 코드 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.