PHPおよびOracleを使用したPayPalオンライン・ペイメント
著者:Nick Bollweg
ユーザーがオンラインで製品を即座に購入するための支援
2006年6月公開
小規模な企業や非営利団体の多くは、オンラインでの支払い処理はユーザーにとって危険で、導入のコストが多大で、既存のシステムと完全には統合できないという誤解のため、オンライン市場への参入をためらいがちです。 実際には、Webサービスの到来とその後の改善により、代金振替の効率は大幅に向上し、サード・パーティ・ベンダーを通じて、どれだけの量のトランザクションであってもほぼ処理できる理想的な方法が提供されています。 もっとも広く知られているものの中で、eBayのPayPalは、競争力のある料金で、そのAPIにアクセスするために使用可能なPHP SDKを提供します。
このレシピでは、このサービスと、PayPalのAPIを使わずアプリケーションの支払い処理をよりいっそう迅速にする方式を概説します。
PayPal
このレシピの例を越えてさらにほかの方法を検討するには、選択したWebサーバー・アプリケーションに接続する、適切に構成されたPHP5のインストールと、PHPへ適切に接続できるOracleデータベースが必要です。 Zend Core for OracleとOracle Database 10g Express Edition(XE)はこの作業に最適なツールです。 オンライン支払い処理では機密事項を扱うため、このサーバーには確実な安全性が必要であり、強固なphp.ini構成が優先事項になります。 PayPal SDKの正常なインストールには、PEAR、cURL、SSLといったいくつかの拡張も必要です。 これらはphp.iniでロードすることもできますが、PHPと同時にコンパイルすると最適な結果が得られます。
環境が適切に設定された状態で、PayPal PHP SDKを
ダウンロードする必要があります。これには、Services/PayPal PEARパッケージ、PayPal WebConsole、SDKドキュメント、およびPDF形式の情報が含まれています(後の"WebConsole不可"セクションでWebConsoleに関する重要な注意点を参照してください)。 ダウンロードとファイルの抽出後に、次のコマンド・ライン操作を実行する必要があります。
pear install --alldeps <location_of_extracted_sdk>/Services_PayPal/package.xml
cp -r <location_of_extracted_sdk>/WebConsole <web_server_document_root>
このコマンドにより、必要に応じてほかのPEARパッケージがインストールされ、PayPal SDKが正しく機能するようにインストールされます。 これが動作するかどうかをチェックするには、ブラウザでhttp://localhost/WebConsoleを参照します。PayPal Profile Admin Tool画面が表示されるはずです。 一般的な誤りとしてcURLおよびSSLがインストールされていないということがあり、これはphp.iniを変更するか、またはPHPを再コンパイルしてから、PEARコマンドを再実行することで修正できます。 ホスティングの制限またはセキュリティの問題により、PEARおよび必要な拡張をインストールできない場合、後述のStandard Checkoutを使用できます。
主な方法
SDKを介するAPIの使用は、PayPalの機能を使用するための柔軟で強力な方法です。 次の2つの支払い方法をこのAPIでは使用できます。
- Direct Payment:Webサイト上で請求の詳細を収集し、ユーザーのクレジット・カードに請求し、ドメインから離れない場合に使用します。 すでに顧客情報やカート情報を保存するためのhttps保護されたアプリケーションやインフラストラクチャがある大企業に適しています。
- Express Checkout:ユーザーは配送方法の選択に加えてPayPalアカウント情報を使用することにより、サイトでその情報を再入力する必要がなくなり、時間が節約されます。 この方法は、買い手の情報のローカル・コピーをアプリケーションが保存する必要をなくし、最小限のセキュリティ・インフラストラクチャを追加するだけで実施できます。
そのほかのAPI機能はこのレシピでは十分に扱ってはいませんが、次の機能が利用可能です。
- Charitable donations:購入に基づく寄付のリアルタイムの情報をユーザーに提供します。
- Shipping:実在の商品の販売では、各種配送ベンダー、配送の種類、保険、そのほかの属性をユーザーが選択できます。 実際に商品を購入する前にユーザーに配送コストをすぐに提示するか、または商品の表示ページでより正確な金額を提示できます。
- Refunds:ユーザーに代金を払い戻す手段を提供します。
- Taxes:受領書および請求書に正確に表示される、品目ごとまたはカートごとの税金を請求します。
- Subscriptions: 実在の、またはデジタル形式での定期購読を柔軟に定義します。
SDKはまた広範なeBayサポートも提供しており、有用ではありますが、ここでは扱いません。
別の方法
ユーザーにはSDKのほとんどの機能が必要ない場合があります。そのため、PayPalには別のソリューションも用意されています。 Standard CheckoutはSOAPを使用せず、アプリケーションとPayPalのセキュア・サーバー間でHTMLフォームの値を受け渡すだけです。 これを使用するには、次の例のような適切なPOST変数を送信できるフォームを生成するだけです。
<form action="https://sandbox.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_cart">
<input type="hidden" name="upload" value="1">
<input type="hidden" name="business" value="sales@widgetco.com">
<input type="hidden" name="item_name_1" value="Big Widget">
<input type="hidden" name="amount_1" value="100.00">
<input type="hidden" name="item_name_2" value="Little Widget">
<input type="hidden" name="amount_2" value="1.00">
<input type="submit" value="PayPal">
</form>
このフォームの送信後、ユーザーは請求情報を入力するPayPalのサーバーに移動します。 情報の検証と請求の認可のメカニズムが終わるとサイトの定義した場所に戻ります。 品物の販売ではなく寄付の収集だけならばこれで完了です。 しかし、そのほかの場合では、このユーザー・エクスペリエンスを機能上、金銭上、表示上の観点からカスタマイズするために、非常に多くの変数を利用できます (『
Reference Guide』参照)。
notify_url変数を指定してInstant Payment Notification(IPN)を使用することで、ユーザーが支払いを完了するとすぐにアプリケーションの選択された場所に通知されるようにできます。カスタマイズされたリンクを使用して専用のユーザー識別子を戻すことができるので、たとえば、オンライン・コンテンツへすぐにアクセスできるようにしたり、卸への注文をトリガーできるようにしたりすることができます。 さらに、請求書やカスタム変数を使用することで、PayPalのレコードをアプリケーションのレコードと結びつける構造を作成できます。 アプリケーションがすでにユーザー名や住所の情報を保存している場合は、address1、city、countryを含む多数の変数としてこの情報をPayPalに渡すことによって、適切なフィールドが事前入力された状態にできます。
商品以外に対する代金の回収のためのAPIにより提供される多くの機能も、Standard Checkoutによる基本的な方法によって扱われます。 つまり、税金、手数料、送料用の変数が存在し、カートごとまたは個々の商品ごとに変数を適用できます。
cpp_ファミリの変数により、PayPalサーバーにおけるユーザー・エクスペリエンスを微調整できます。これにはcpp_header_image、cpp_headerback_color、cpp_headerborder_color、および支払いページの背景色を設定するcsが含まれます。 この方法によりアプリケーション要件が満たされる場合、Standard Checkoutは非常にコスト効率のよいソリューションになります。 APIベースのDirect Paymentとは異なり、月額使用料はかからず、実装時に必要な開発も抑えられます。
支払いの準備
PayPal APIを使用するには、まずDeveloper Centerについてよく知る必要があります。 ここでアカウントを作成し、Sandboxにサンプルの売り手アカウントと買い手アカウントを作成します。 作成したら、Sandboxにサンプルのアカウントでログインし、架空のお金で動作するPayPalアカウントを表示します。 ほかのSandboxアカウントから、買い手は購入でき、売り手は払い戻すことができます。すべて実際のお金の所有者の変更およびPayPalの手数料はありません。 優れた
手順ごとの説明がPayPalのIntegration Centerで利用可能ですが(これのステップ3が前述したインストールプロセスです)、ここでも概要を説明します。
最初に、
developer.paypal.comのアカウントが必要です。これは開発者リソースのさまざまな局面にアクセスするための中心点であり、Sandboxアカウントの作成にも必要です。 次に、developer.paypal.comの「
Sandbox」タブでサンプルの売り手と買い手を作成します。 これは比較的簡単で、わかりやすくするために十分な程度の創造性を発揮する必要があるだけです。 たとえば、銀行口座情報を追加するメカニズムが提供される場合、容易に参照できるように、提供された架空の口座番号を銀行の名前として使用するとよいでしょう。 さらに、このサーバーに対する攻撃のリスクは低いので、売り手と買い手のアカウントに同じパスワードを使用したほうがよいでしょう。 このSandboxで習得した機能は、本番環境で使用されるものとまったく同じであり、これによりトレーニングとテストの時間が削減されます。
Sandboxでの最後の重要なステップはTest Certificateの作成です。これはあらゆるAPI呼出しで使用される暗号化キーを含む小さなテキスト・ファイルです。 証明書を作成するには、売り手のSandboxアカウントにログインし、「
Profile」、「
API Access」、そして「
View or Remove Credentials」をクリックする必要があります。 アプリケーションの構成時に必要になるので、このファイルとパスワードを保管します。
developer.paypal.comに戻り、「
Test Certificates」タブでTest Certificateの情報を表示し、ダウンロードできます。 ただし、APIパスワードをここで表示することはできません。この情報を取得するには、
http://www.sandbox.paypal.com/に再度ログインし、上記の場所に移動する必要があります。
Direct Paymentの処理
PayPalを利用するためのもっとも柔軟な方法はSDKを介することです。これはSOAPベースのリクエストを管理しやすいレベルに抽象化します。 呼出しが異なれば達成される目標も異なりますが、手順は一般的に類似しており、認証、アクション、応答処理です。 最初の手順の認証は、SDKの例から改変されるもので、後述のExpress Checkout方式でも必要になります。 次に示す値はSandboxテスト用です。 本番環境用には、認証の詳細がある新しい証明書を作成する必要があります。
$certfile = dirname(__FILE__) . '/sdk-seller_cert.pem';
$apiusername = '<your API username>';
$apipassword = '<your API password>';
$subject = null;
$environment = 'Sandbox';
$handler =& ProfileHandler_Array::getInstance(array(
'username' => $apiusername,
'certificateFile' => $certfile,
'subject' => $subject,
'environment' => $environment));
$profile =& APIProfile::getInstance($apiusername, $handler);
$profile->setAPIPassword($apipassword);
$caller =& Services_PayPal::getCallerServices($profile);
認証後、アプリケーションはAPIリクエストを処理できるようになります。 Direct Paymentでは、アプリケーションに注文の作成、その状態の保存、受領書の作成をおこなう機能と信頼性を持たせる必要があります。 次の例では、アプリケーションが関連する情報すべてをCustomer、Billing_Method、Order、およびLine_item表に保存していると仮定します。 従来からあるOCI8方式も使用できますが、この例では
PHPデータ・オブジェクト(PDO)を使用しています。
$db = new PDO('oci:', 'scott', 'tiger' 'HR', 'HR');
$dbcustomer = $dbh->query("SELECT * " .
"FROM customer " .
"WHERE customerid = '{$_SESSION[customerid]'}");
$dborder = $dbh->query("SELECT * " .
"FROM order " .
"WHERE customerid = '{$_SESSION[customerid]}' " .
"AND orderid = '{$_SESSION[orderid]}'");
$dbbilling = $dbh->query("SELECT * " .
"FROM billing_method " .
"WHERE billingid = '{$dborder[billingid]}'");
$dblineitemtotals = $dbh->query("SELECT sum(amount) total " .
"FROM line_item " .
"WHERE customerid = '{$_SESSION[customerid]}' " .
"AND orderid = '{$_SESSION[orderid]}'");
$name =& Services_PayPal::getType('PersonNameType');
$name->setFirstName($dbcustomer['fname']);
$name->setLastName($dbcustomer['lname']);
$address =& Services_PayPal::getType('AddressType');
$address->setStreet1($dbbilling['street1']);
$address->setCityName($dbbilling['city']);
$address->setStateOrProvince($dbbilling['state']);
$address->setCountry($dbbilling['country']);
$address->setPostalCode($dbbilling['zip']);
$payer =& Services_PayPal::getType('PayerInfoType');
$payer->setPayerName($name);
$payer->setPayerCountry('US');
$payer->setAddress($address);
$cc =& Services_PayPal::getType('CreditCardDetailsType');
$cc->setCreditCardType($dbbilling['cardtype']);
$cc->setCreditCardNumber($dbbilling['cardnumber']);
$cc->setExpMonth($dbbilling['expmonth']);
$cc->setExpYear($dbbilling['expyear']);
$cc->setCardOwner($payer);
$amount =& Services_PayPal::getType('BasicAmountType');
$amount->setval($dblineitemtotals['total']);
$amount->setattr('currencyID', 'USD');
$pdt =& Services_PayPal::getType('PaymentDetailsType');
$pdt->setOrderTotal($amount);
$details =& Services_PayPal::getType('DoDirectPaymentRequestDetailsType');
$details->setPaymentAction('Authorization');
$details->setPaymentDetails($pdt);
$details->setCreditCard($cc);
$details->setIPAddress('127.0.0.1');
$details->setMerchantSessionId('merchantId');
$ddp =& Services_PayPal::getType('DoDirectPaymentRequestType');
$ddp->setDoDirectPaymentRequestDetails($details);
この時点で、PayPalは要求されたDirect Paymentを実行します。 実行内容を調査するには、3番目の手順である応答処理で、アプリケーションにより情報を取得します。
$response = $caller->DoDirectPayment($ddp);
このレスポンスで返されるさまざまなフィールドは、トランザクションIDだけでなく、正常に終了したトランザクションに関する情報も提供します。 このIDを保存し、後のAPI呼出し時に提供することで、アプリケーションはトランザクションの詳細を取得できます。したがって別の表に保存しておく価値があります。
$d =& Services_PayPal::getType('GetTransactionDetailsRequestType');
$d->setTransactionId('<transaction ID from above>');
$response = $caller->GetTransactionDetails($d);
WebConsole不可
執筆時点では、前述のSDKダウンロードで提供されるWebConsoleは壊れていて、重要なディレクトリがありません。 しかし、必要なすべてのファイルを含むアーカイブをダウンロードすることはできます。 このコンソールはAPI呼出しのテストとPHPコード・スニペットの生成の機能を提供し、目的に合わせて改変できます。 ここでの調査とSDKリファレンスにより、自分のブラウザから快適に、サンドボックスに対してすべてのAPI呼出しを検討できます。
Express Checkout
Express Checkoutは、Direct Paymentの能力とStandard Checkoutの簡潔さの間に位置します。 Express Checkoutを使用するAPIベース方式では、ユーザーはサイト内で注文作成のプロセスを完結してからPayPalに進み、請求と配送情報を処理します。 ユーザーはExpress Checkoutを使用するすべての取引に対し、この情報を1度入力するだけでよく、アプリケーションがそれを保存する必要はありません。これはセキュリティおよび開発上の大きな利点です。 前述のように、トランザクションIDを保存することにより、アプリケーションはAPI呼出しを追加して詳細を取得できます。 Express Checkoutは前述のIPNを使用でき、リアルタイムの処理オプションを追加することが可能です。 次のスニペットはSDKの例を改変したものです。
$amount =& Services_PayPal::getType('BasicAmountType');
$amount->setval(<amount determined by your page>);
$amount->setattr('currencyID', 'USD');
$ecd =& Services_PayPal::getType('SetExpressCheckoutRequestDetailsType');
$ecd->setOrderTotal($amount);
$ecd->setReturnURL('http://widgetco.com/return');
$ecd->setCancelURL('http://widgetco.com/cancel');
$ec =& Services_PayPal::getType('SetExpressCheckoutRequestType');
$ec->setSetExpressCheckoutRequestDetails($ecd);
$response = $caller->SetExpressCheckout($ec);
この呼出しの結果によりトークンが提供され、それをリンクに追加するか、またはサイトでPayPalへリダイレクトします。 それからユーザーはPayPalを使用して操作を行い、成功または失敗するとすぐに、サイトへリダイレクトされます。 この例では、returnというページがアプリケーションに対し次のAPI呼出しを実行します。
$ecd =& Services_PayPal::getType('GetExpressCheckoutDetailsRequestType');
$ecd->setToken('<token from above>');
$response = $caller->GetExpressCheckoutDetails($ecd);
これには有用なトランザクションに関するすべての情報が含まれていますが、クレジット・カード番号のような機密情報は含まれません。 ユーザーがサイトでこれらの値を確認したら、最後のAPI呼出しが実際に代金のトランザクションを実行します。
$amount =& Services_PayPal::getType('BasicAmountType');
$amount->setval(<amount from above>);
$amount->setattr('currencyID', 'USD');
$pdt =& Services_PayPal::getType('PaymentDetailsType');
$pdt->setOrderTotal($amount);
$details =& Services_PayPal::getType('DoExpressCheckoutPaymentRequestDetailsType');
$details->setPaymentAction('Sale');
$details->setToken('<token from above>');
$details->setPayerID('juser@jisp.com');
$details->setPaymentDetails($pdt);
$ecprt =& Services_PayPal::getType('DoExpressCheckoutPaymentRequestType');
$ecprt->setDoExpressCheckoutPaymentRequestDetails($details);
$response = $caller->DoExpressCheckoutPayment($ecprt);
同様に、updateChartが呼び出されると、ChartDataがonResultメソッドを起動します。
_root.chartData.onResult = function() {
_root.chart.throbber._visible = false;
drawChart(this);
}
Express CheckoutはStandard Checkoutのプライバシとセキュリティの利点を保持しながら、Direct Paymentとほぼ同様にカスタマイズできます。
最後に
PayPal支払い処理は、いずれの形態であっても、効率的なオンラインでの支払いの受取り方法を提供します。 どのモデルが最適かは実装担当者が判断します。 Standard Checkoutはセキュリティ・アーキテクチャへの追加投資なしで小規模の組織に支払いの受取り機能を提供し、Direct Paymentは既存のエンタープライズ・アプリケーションと統合する場合に理想的であり、Express Checkoutは中間の立場を提供して、サード・パーティ製品への順応に適しています。 柔軟性、セキュリティ、および実装しやすさのバランスを選択することで、既存のOracleインフラストラクチャを活用してオンライン支払いの利用機会を獲得できます。
Nick Bollweg [
nick.bollweg@gmail.com]はメリーランド州ボルチモア在住のフリーランスのWeb開発者です。
ご意見ご感想をお寄せください。
|