MJHD

エモさ駆動開発

PayPalで定期支払いをする

PayPalでは公式のサンプルコードが手に入り,それを使うことでExpressCheckoutという一番簡単な決済方法を使うことができる. だがPayPalにはもう一つの支払い方法として定期支払い(Recurring)が存在する. 今回はそのメモ.

ちなみに,今回使うpaypalfunctions.phpファイルはここで手に入る.

定期支払い関数を作る

paypalfunctions.phpを編集して,以下のコードを追加する.


    function CallRecurringExpressCheckout( $billingDescription, $currencyCodeType, $paymentType, $returnURL,
                                      $cancelURL)
    {
        //------------------------------------------------------------------------------------------------------------------------------------
        // Construct the parameter string that describes the SetExpressCheckout API call in the shortcut implementation
        
        $nvpstr="&L_BILLINGTYPE0=RecurringPayments";
        $nvpstr = $nvpstr . "&L_BILLINGAGREEMENTDESCRIPTION0=" . $billingDescription;
        $nvpstr = $nvpstr . "&RETURNURL=" . $returnURL;
        $nvpstr = $nvpstr . "&CANCELURL=" . $cancelURL;
        
        $_SESSION["currencyCodeType"] = $currencyCodeType;    
        $_SESSION["PaymentType"] = $paymentType;

        //'--------------------------------------------------------------------------------------------------------------- 
        //' Make the API call to PayPal
        //' If the API call succeded, then redirect the buyer to PayPal to begin to authorize payment.  
        //' If an error occured, show the resulting errors
        //'---------------------------------------------------------------------------------------------------------------
        $resArray=hash_call("SetExpressCheckout", $nvpstr);
        $ack = strtoupper($resArray["ACK"]);
        if($ack=="SUCCESS" || $ack=="SUCCESSWITHWARNING")
        {
            $token = urldecode($resArray["TOKEN"]);
            $_SESSION['TOKEN']=$token;
        }
           
        return $resArray;
    }

    function CreateRecurringPaymentsProfile($fromDate, $description, $amount, $currencyCodeType, $period, $frequency, $token) {
        $nvpstr="&PROFILESTARTDATE=" . $fromDate;
        $nvpstr = $nvpstr . "&CURRENCYCODE=" . $currencyCodeType;
        $nvpstr = $nvpstr . "&AMT=" . $amount;
        $nvpstr = $nvpstr . "&DESC=" . $description;
        $nvpstr = $nvpstr . "&BILLINGPERIOD=" . $period;
        $nvpstr = $nvpstr . "&CURRENCYCODE=" . $currencyCode;
        $nvpstr = $nvpstr . "&BILLINGFREQUENCY=" . $frequency;
        $nvpstr = $nvpstr . "&TOKEN=" . $token;
        
        $_SESSION["currencyCodeType"] = $currencyCodeType;    
        $_SESSION["PaymentType"] = $paymentType;

        //'--------------------------------------------------------------------------------------------------------------- 
        //' Make the API call to PayPal
        //' If the API call succeded, then redirect the buyer to PayPal to begin to authorize payment.  
        //' If an error occured, show the resulting errors
        //'---------------------------------------------------------------------------------------------------------------
        $resArray=hash_call("CreateRecurringPaymentsProfile", $nvpstr);
        $ack = strtoupper($resArray["ACK"]);
        if($ack=="SUCCESS" || $ack=="SUCCESSWITHWARNING")
        {
            $token = urldecode($resArray["TOKEN"]);
            $_SESSION['TOKEN']=$token;
        }
           
        return $resArray;
    }

そして,この関数を呼び出すPHPファイルは以下のように記述する.


      $planAmount = 3980;
      $planDescription = "定期支払い(毎月) ".$planAmount."円";
      $returnURL = "http://localhost/review.php";
      $cancelURL = "http://localhost/";

      // 後で使う
      $_SESSION["desc"]   = $planDescription;
      $_SESSION["amount"] = $planAmount;

        $resArray = CallRecurringExpressCheckout ($planDescription, $currencyCodeType, $paymentType, $returnURL, $cancelURL);

    $ack = strtoupper($resArray["ACK"]);
    if($ack=="SUCCESS" || $ack=="SUCCESSWITHWARNING")
    {
        $token = urldecode($resArray["TOKEN"]);
        $_SESSION['reshash']=$token;
        RedirectToPayPal ( $token );
    } 
    else  
    {
        //Display a user friendly Error on the page using any of the following error information returned by PayPal
        $ErrorCode = urldecode($resArray["L_ERRORCODE0"]);
        $ErrorShortMsg = urldecode($resArray["L_SHORTMESSAGE0"]);
        $ErrorLongMsg = urldecode($resArray["L_LONGMESSAGE0"]);
        $ErrorSeverityCode = urldecode($resArray["L_SEVERITYCODE0"]);
        
        if ($ini["debug"]) {
            echo "SetExpressCheckout API call failed. ";
            echo "Detailed Error Message: " . $ErrorLongMsg;
            echo "Short Error Message: " . $ErrorShortMsg;
            echo "Error Code: " . $ErrorCode;
            echo "Error Severity Code: " . $ErrorSeverityCode;
        }
    }

ちなみにこの段階では定期支払いの期間,料金の設定などは要らないらしい.

そして,GetShipmentDetail関数を呼び出すreview.phpを作成し, その後,定期支払いを確定する以下のPHPスクリプトを作成する.

(POSTでreview.phpからGetShipmentDetailで取得したTOKENを受け取ってる前提)


            $currencyCodeType = "JPY";

            $resArray = CreateRecurringPaymentsProfile((new DateTime())->format("c"), $_SESSION["desc"], $_SESSION["amount"], $currencyCodeType, "Month", 1, $_POST["token"]); // 一ヶ月の定期支払い
            
            $ack = strtoupper($resArray["ACK"]);
            if ($ack == "SUCCESS" || $ack == "SUCCESSWITHWARNING") {
                info("支払いに成功しました.");
            } else {
                fatal("支払いに失敗しました.", var_dump($resArray));
            }