PayPal エクスプレスチェックアウト (API 決済) の使い方
[履歴] [最終更新] (2016/08/15 05:06:17)
10
作品
8
技術情報
最近の投稿
ここは
趣味の電子工作を楽しむ人のためのハードウェア情報共有サイト

技術情報や作品の投稿機能、リアルタイム遠隔操作 API をご利用いただけます。
新着作品

概要

インターネット上に自分の商品の販売ページを生成する方法は Amazon に出店BASESTORES.jpSPIKE など様々です。そうではなく、ここでは商品ページは自サイトにあり、決済手段だけを導入したい場合を考えます。具体的には、審査が通った一部の法人向けに昨年から日本でも利用できるようになった Amazon ログイン&ペイメントや、開発者向けドキュメントが充実している日本発の WebPay の類の決済手段です。ここでは特に eBay などを含み世界的にも標準の決済手段である PayPal を対象とします。最新のドキュメントが日本語化されておらず、開発時の情報が不足している状況が少しでも改善されればと思い、その使い方をまとめます。ここでは法人または個人事業主としてのビジネスアカウントの開設および本人確認手続きは完了しているものとします。プレミアアカウントでも問題ありません。Business と Premier の他には Personal, Student があります。

エクスプレスチェックアウト (API 決済) について

PayPal が提供する決済手段には、請求用のリンクが記載されたメールの送付、静的な HTML の埋め込み、OAuth を利用した動的な API 決済などがあります。本ページでは、エクスプレスチェックアウトとよばれる API 決済を対象とします。

公式ドキュメント

英語ドキュメント

本ページの内容を越えるものは、以下の公式ドキュメントを参照してください。

日本語ドキュメント (2016/08/14 現在、情報が古いため参考情報扱い)

日本語ドキュメントでは NVP/SOAP の記載なされていますが、英語ドキュメントでは Classic 扱いです。REST API を利用しましょう。

認証情報やテストアカウントを事前に準備

  • merchant ID
    1. PayPal アカウントでログイン
    2. 右上の「アカウント設定」→「プロフィール設定」
    3. マーチャントアカウントID XXXXXXXXXXXXX を確認
  • client_id and secret
    1. PayPal アカウントでログイン (ドキュメント内ですが、右上の LogIn ボタンからログインできます)
    2. "My Apps & Credentials" → "REST API apps" → "Create App"
    3. Client IDSecret を Sandbox (テスト環境) と Live に関して確認
  • Sandbox Test Accounts
    • テスト環境で使用するためのダミーアカウントを二つ用意します (facilitator 売り手と buyer 買い手)

PayPal 支払いボタンの設置

公式ドキュメントでサンプルコードとして示されている以下の HTML を自分のサイトに組込みます。

<form id="myContainer" method="post" action="/checkout"></form>
<script>
window.paypalCheckoutReady = function() {
    paypal.checkout.setup('Merchant-ID', {
        environment: 'sandbox',
        container: 'myContainer'
    });
};
</script>
<script src="//www.paypalobjects.com/api/checkout.js" async></script>

checkout.js は最新のものを外部から都度読み込んで使用します。id が myContainer の form タグを container に指定することで、支払いボタン用の CSS が form タグに適用されます。Merchant-ID は事前に取得した XXXXXXXXXXXXX に書き換えてください。/checkout は PayPal に対して REST で API 実行するためのエンドポイントです。次のステップで実装します。

Rails を用いたサンプルコード

買い手が何らかの商品を指定した状態で先程設置した支払いボタンをクリックすると /checkout 向けに HTTP POST リクエストが発生します。/checkout はこれに対し、今から買い手に請求する予定の内容を HTTP POST で PayPal REST API に送信します。PayPal API が正しいサイトからのリクエストであると判断すると、買い手が PayPal ログインするために必要な情報が含まれたレスポンスが返されます。/checkout はこれらの情報をもとに買い手を PayPal のページにリダイレクトします。/checkout を実装するためには、こちらのチュートリアルにしたがって REST API に対して HTTP POST すればよいのですが、各プログラミング言語用の SDK を利用すると比較的簡単に実装できます。ここでは特にこちらのページで bundler が導入済みの Rails で ruby SDK を利用する場合を考えます。

Gemfile

gem 'paypal-sdk-rest'

設定ファイルの生成

bundle exec rails g paypal:sdk:install

app/views/main/index.html.erb (Rails の場合は CSRF の機能があるため POST に form_authenticity_token を含めます)

<form id="myContainer" method="post" action="/checkout">
  <input type="hidden" value="<%= form_authenticity_token %>" name="authenticity_token">
</form>
<script>
window.paypalCheckoutReady = function() {
    paypal.checkout.setup('Merchant-ID', {
        environment: 'sandbox',
        container: 'myContainer'
    });
};
</script>
<script src="//www.paypalobjects.com/api/checkout.js" async></script>

config/routes.rb

post '/checkout' => 'paypal#checkout'
get '/execute' =>  'paypal#execute'

app/controllers/paypal_controller.rb

class PaypalController < ApplicationController

  def checkout
    # 仮に、計 200 円の商品が買い物かごの中に入っていたとします。
    payment = PayPal::SDK::REST::Payment.new({
      intent: 'sale',
      payer: {
        payment_method: 'paypal',
      },
      redirect_urls: {
        return_url: 'http://localhost:3000/execute', # 買い手の承認が得られた場合の遷移先
        cancel_url: 'http://localhost:3000/', # 買い手がキャンセルしたときの遷移先
      },
      transactions: [
        {
          amount: {
            total: 200,
            currency: 'JPY',
          },
          item_list: {
            items: [
              {
                price: 100,
                currency: 'JPY',
                quantity: 1,
                name: 'サンプルアイテム A', # 日本語を使用する場合、本ファイルは UTF-8 で保存しましょう。
              },
              {
                price: 50,
                currency: 'JPY',
                quantity: 2,
                name: 'サンプルアイテム B', # 日本語を使用する場合、本ファイルは UTF-8 で保存しましょう。
              },
            ],
          },
        },
      ]})

    # PayPal API に HTTP POST リクエストを行い、その結果で処理を分岐します。
    if payment.create
      redirect_to payment.links.find{|v| v.rel == 'approval_url'}.href
    else
      render text: payment.error # 何らかのエラー処理を行います。
    end
  end

  def execute
    # 買い手の PayPal アカウントから売り手の PayPal アカウントへの支払いを実行します。
    payment = PayPal::SDK::REST::Payment.find(params[:paymentId])

    # 配送先の住所が必要な場合は以下のように格納されています。
    # 最終確認をしたい場合は execute の前に 1 ページ画面をはさみましょう。
    #payment.transactions.first.item_list.shipping_address 

    if payment.execute(payer_id: params[:PayerID]) # 本サンプルではそのまま決済を確定させます。
      render text: '決済が完了しました。'
    else
      render text: payment.error # 何らかのエラー処理を行います。
    end
  end
end

決済ボタンのデザインを変更する

checkout.js のソースコードを確認すると、container ではなく button を指定すれば任意のデザインのボタンを決済ボタンに指定できることが分かります。

<form method="post" action="/checkout">
  <input type="hidden" value="<%= form_authenticity_token %>" name="authenticity_token">
  <button id="myButton" class="btn btn-default">PayPal でお支払い</button>
</form>
<script>
window.paypalCheckoutReady = function() {
    paypal.checkout.setup('Merchant-ID', {
        environment: 'sandbox',
        button: 'myButton'
    });
};
</script>
<script src="//www.paypalobjects.com/api/checkout.js" async></script>
関連ページ