PayPalの購入処理をアプリに組み込む

これも、スクレイピングになるのかな?

有料アプリもユーザーに購入していただくさい、アプリで購入してすぐに利用制限が解除されると便利ですよね!

PayPalは様々なAPIを提供しているのでスマホのアプリで決済したりウインドウズのアプリで決済したりできます。

PayPalのAPIは次のような流れで処理ができます。

  1. SetExpressCheckout
    paypalのAPIに購入商品情報を送ってトランザクションIDを発行してもらいます。
  2. ユーザーに購入画面を表示 クレジット決済ができます。
    WebView2等でユーザーが購入するためのページを表示します。

    この時1.で入手したトランザクションIDを一緒に送ると1.登録した商品情報が掲示されます。
    ユーザーがクレジット情報などを入力して購入確認ボタンを押す

  3. GetExpressCheckoutDetails
    アプリ側で認識のための情報を取得し、また、トランザクションIDをPayPalのAPIに送る。
    買う意思があるので次の処理に進めるよ!っていう意味なのかな?
  4. ユーザーが購入の意思を再確認のOKボタン
    ここで、ユーザに購入の意思があるかをアプリ側のOKボタンを押してもらう必要があります。
    ユーザーの意思に関係なくアプリ側で処理を進めることも可能ですが、この場合NGのようです。
  5. DoExpressCheckoutPayment
    ユーザーがアプリ側のOKボタンで購入完了の処理を送ります。
    この時3で得た情報のいくつかを一緒にAPIに送る必要があります。

    APIから購入が完了したことを告げるメッセージの応答があります。
    この時のトランザクションIDをファイルなどに保存してお行きます。

購入履歴の確認

  1. GetTransactionDetails
    アプリが保存したトランザクションIDを使って取得できます。
    私の場合は、パソコンのプロダクションIDと購入時の日付をPayPalの購入履歴に

    記録しているので365日経過したらやPCの入替をしたら、利用制限がかかるなどの
    対策をしています。

 

プログラミング
PayPalのAPIに送るデータがなかなか難しいのでここに載せてておきます。少しだけ説明を記載したのでわかるかな? 必需って書いてるのが間違っちゃダメな項目この設定情報で最初のAPIの処理を行います。

1.SetExpressCheckout


NameValueCollection ps = NewMethod();
//PayPalへの接続開始処理
ps.Add("METHOD", "SetExpressCheckout");
ps.Add("USER", "tm.yamada_api1.icloud.com");
ps.Add("PWD", PWD);
ps.Add("SIGNATURE", SIGNATURE);
ps.Add("VERSION", "124");
string[] datas = new string[] { };
if (cultures.ToLower() == "ja-jp")
    datas = "JPY,1650,1500,150".Split(',');//"JPY,1650,1500,150".Split(',');
else
    datas = "US,16.5,15,1.5".Split(',');
ps.Add("PAYMENTREQUEST_0_CURRENCYCODE", datas[0]); //PAYMENTREQUEST_0_CURRENCYCODE) '日本円
ps.Add("PAYMENTREQUEST_0_AMT", datas[1]); //買い手への総額 PAYMENTREQUEST_0_AMT = PAYMENTREQUEST_0_ITEMAMT + PAYMENTREQUEST_0_TAXAMT
ps.Add("PAYMENTREQUEST_0_ITEMAMT", datas[2]);//価格必需
ps.Add("PAYMENTREQUEST_0_TAXAMT", datas[3]); //消費税 必需
DateTime now = DateTime.Now;
set_key = now.ToString("d") + "," + PC_SN;
ps.Add("PAYMENTREQUEST_0_DESC", set_key);// 'ここに書かれている事がGetTransactionDetailsで取得できるTRANSACTIONIDが必要
ps.Add("PAYMENTREQUEST_0_CUSTOM", "ABCDEFG");// '特に取得できない
ps.Add("PAYMENTREQUEST_0_PAYMENTACTION", "Sale");//
ps.Add("L_PAYMENTREQUEST_0_NAME0", "ReNamePDF");// '商品名必需項目
ps.Add("L_PAYMENTREQUEST_0_ITEMCATEGORY0", "Physical");// 'デジタルコンテンツの場合は必需 Digital  Physical
ps.Add("L_PAYMENTREQUEST_0_AMT0", datas[2]);// '一個なのでPAYMENTREQUEST_0_ITEMAMTと同じ金額 商品の金額 必需
ps.Add("REQCONFIRMSHIPPING", "0");// 'デジタルコンテンツで送り先は不要のため 0 とする
ps.Add("NOSHIPPING", "1");// 'デジタルコンテンツの場合必要 1とする
ps.Add("ALLOWNOTE", "0");// '買い手からのコメントは不要なので0とする
ps.Add("SOLUTIONTYPE", "Sole");// '買い手がPaypalアカウントを持っていなくても購入可能
ps.Add("BRANDNAME", "CapsuleContents");// 'サイト名だが表示はされない
ps.Add("RETURNURL", "https://capsulecontents.ーーーー.coreserver.jp/ーーーー/paypal/ok/");
ps.Add("CANCELURL", "https://capsulecontents.ーーーー.coreserver.jp/ーーーー/paypal/no/");

//通信処理
using (WebClient wc = new WebClient())
{
    wc.UploadValuesCompleted += Wc_SetExpressCheckoutCompleted;
    wc.UploadValuesAsync(new Uri("https://api-3t.paypal.com/nvp"), ps);
}; 

 

次に応答情報は次のように取得します。
2.ユーザーに購入画面を表示 クレジット決済ができます。


private void Wc_SetExpressCheckoutCompleted(object sender, UploadValuesCompletedEventArgs e)
{
    string resText = HttpUtility.UrlDecode(Encoding.UTF8.GetString(e.Result));
    restets = resText.Split('&');
    WebClient wc = (WebClient)sender;
    wc.UploadValuesCompleted -= Wc_SetExpressCheckoutCompleted;

    if (restets[0].IndexOf("TOKEN") != -1)
    {
        TOKUN = restets[0].Split('=')[1];
        webView21.CoreWebView2.Navigate("https://www.paypal.com/jp/" +
            "cgi-bin/webscr?cmd=_express-checkout&useraction=commit&" + restets[0] + "&useraction=continue#/checkout/login");
    }
}

ユーザーがWebView2で処理が終わると次の処理です。

3.GetExpressCheckoutDetails
WebView2のNavigationComletedから処理していきます。
ここではトークンをPayPalのAPIに送るだけですね。


if (url_paypal.IndexOf("jp/ーーーー/paypal/ok/") != -1)
{
    NameValueCollection ps = NewMethod();

    //PayPalへの接続開始処理
    ps.Add("METHOD", "GetExpressCheckoutDetails");
    ps.Add("USER", "tm.yamada_api1.icloud.com");
    ps.Add("PWD", PWD);
    ps.Add("SIGNATURE", SIGNATURE);
    ps.Add("VERSION", "124");
    ps.Add("TOKEN", TOKUN);

    //通信処理
    using (WebClient wc = new WebClient())
    {
        wc.UploadValuesCompleted += Wc_GetExpressCheckoutDetailsCompleted;
        wc.UploadValuesAsync(new Uri("https://api-3t.paypal.com/nvp"), ps);
    };

PayPalのAPIから返答があったら、かなりの情報が送られてきます。
この状態になったら、ユーザーにOKボタンを表示して 押すように促します。

4.ユーザーが購入の意思を再確認のOKボタン
OKボタンを表示したり、アクティブにしたりします。

5.DoExpressCheckoutPayment

ボタンのプログラムは次のようになります。
ユーザーがちゃんと押したよ!かったよ!ってPayPalのAPIに報告します。


NameValueCollection ps = NewMethod();

//PayPalへの接続開始処理
ps.Add("METHOD", "DoExpressCheckoutPayment");
ps.Add("USER", "tm.yamada_api1.icloud.com");
ps.Add("PWD", PWD);
ps.Add("SIGNATURE", SIGNATURE);
ps.Add("VERSION", "124");
foreach (string s in restets)
{
    string[] res = s.Split('=');

    if (res[0] == "TOKEN")
        ps.Add("TOKEN", res[1]);

    if (res[0] == "PAYERID")
        ps.Add("PAYERID", res[1]);

    if (res[0] == "PAYMENTREQUEST_0_ITEMAMT")
        ps.Add("PAYMENTREQUEST_0_ITEMAMT", res[1]);

    if (res[0] == "PAYMENTREQUEST_0_TAXAMT")
        ps.Add("PAYMENTREQUEST_0_TAXAMT", res[1]);

    if (res[0] == "PAYMENTREQUEST_0_AMT")
        ps.Add("PAYMENTREQUEST_0_AMT", res[1]);

    if (res[0] == "PAYMENTREQUEST_0_CURRENCYCODE")
        ps.Add("PAYMENTREQUEST_0_CURRENCYCODE", res[1]);
}
ps.Add("PAYMENTREQUEST_0_NOTIFYURL", "https://capsulecontents.ーーーー.coreserver.jp/ーーーー/paypal/ok/");//この取引に関する即時支払い通知用?

//通信処理
using (WebClient wc1 = new WebClient())
{
    wc1.UploadValuesCompleted += Wc_DoExpressCheckoutPaymentCompleted;
    wc1.UploadValuesAsync(new Uri("https://api-3t.paypal.com/nvp"), ps);
};

 

APIからの返答でエラーが無ければトランザクションIDをユーザーのパソコンに保存します。
この時の返答内容に"PAYMENTREQUEST_0_DESC"がありませんのでプログラム内で取っておいて
トランザクションIDと一緒に保存しておくといいです。

"PAYMENTREQUEST_0_DESC"は売り手が自由に設定できて購入履歴を取得したときにこの情報が
取得できます。わたしは、パソコンに保存されている"PAYMENTREQUEST_0_DESC"と比較に使用しています。

PayPalのAPIにはsandboxがあってテストユーザーを複数に作って実際に購入したりするためのテストサーバーがあります。

私は利用していませんが(笑)販売課価格を1円にしてクレジットカードで購入してます。PayPalのアカウントは二つ持ってて売買用ビジネスアカウントと買いようのアカウントですね!

売買用のアカウントでなきゃAPI利用できないので注意してくださいね!PayPalのAPIを利用する方法でした。ちなみに、ReNamePDFは完成しました。

現在動作チェックを行っています。エラーはほぼなくなったので、9月12日くらいにはアップできると思います。しかし?まだ、 スキャナーでとったような画像には対応していないのでもうしばらくお待ちください。

こちらが完成したReNamePDFです。メモ帳の内容は設定ファイルですね。
右の画面がWebView2の画面でPayPalのAPIに接続して購入するために「注文の確認を続ける」のボタンをタップすると次の画面に移行します。

 

こちらが、注文の確認の次に表示される内容ですね、アプリ側でOKボタンを表示させています。
このOKボタンを押すと購入が確定します。私がOKボタンをおすと手数料だけ取られるのでここで×で画面消します!

ちなみに動作チェック時は販売価格を1円にして消費税は0円ですねこのように設定してもう一つのアカウントで購入してテストしています。