web-dev-qa-db-ja.com

登録時の支払いは?

ケーススタディ:

彼らが私のサイトに登録するようになるとき私は人々が私に支払う必要があります。ページの大部分は、ログインしているユーザーしか利用できないはずです。 Paypalは私の支払いオプションになります。

質問?

ユーザーが支払いをしたかどうかの支払いを行った後、どうやってPaypalと通信できるのかを知る必要がありますか?

2
Choudhury A. M.

最善の方法は、ユーザーロールでこれを処理することです。ユーザーは登録できますが読むことはできません。 Paypalで支払いをした後、役割は更新されます(例えば、読者から購読者へ)。更新はPayPals IPNを介して行うことができます。

私は私のクライアントの一人のためにこれを作りました。あなたはあなたの顧客によって支払われるでしょう。私はあなたが支払います。あなたはプラグインを手に入れました。

更新

あなたがテーマを書きたいと思っていて、あなたの職業上の目的のためにそれを使わなかったので、ここに私のプラグイン解決策のいくつかの部分があります。

ペイパルIPN

Paypal IPNから始めましょう。 Paypalはよく文書化されたAPIと Paypal開発者ネットワーク を持っています。開発者ネットワークのアカウントが役に立ちます。Paypalにはサンドボックスとたくさんのスクリプトとチュートリアルがあります。
開発ネットワークを掘り下げてみると、IPN(Instant Payment Notification)が見つかりました。 IPNとは、Paypalが、PayPalアカウントで指定したURLに、支払人に関する詳細情報を含む投稿要求を送信することを意味します。開発中、あなたは IPNシミュレータ を気に入るはずです。
最初の実験用スクリプトを始めましょう。 Paypal IPN simulatroにアクセスしてください(上記のリンクを参照)。シミュレータが最初に必要とするのは、あなたのスクリプトへのURLです。 PayPalは投稿リクエストでデータを送信するので、あなたはあなたのローカルウェブサーバーを使用することはできません、あなたは公共のものを必要とします。あなたのサーバーがhttp://yourdoma.inの下で到達可能であると仮定して、それからftp(例えばそれをpplog.phpと命名する)で以下のスクリプトをアップロードして、そしてフィールドにhttp://yourdoma.in/pplog.phpを入力するかIPN handler URL。次のドロップダウンからCart checkoutを選択してSend IPNをプッシュします。

<?php
if (empty($_POST))
    exit( 'No post request' );

define('MAILMODE', true);

$filename    = 'Paypal-ipn.log';
$file_exists = file_exists(filename);

if ($file_exists && MAILMODE) {
    unlink($filename);
    $mode = 'w';
} else {
    $mode =  $file_exists ? 'a+' : 'w';
}

$handle = fopen($filename, $mode);
if ( $handle ) {
    fputs($handle, date( 'Y-m-d')."\n");
    fputs($handle, var_export( $_POST, true));
    fputs($handle, "\n");
    fputs($handle, str_repeat('-', 80)."\n");
    fclose($handle);
}

if (MAILMODE)
    mail('[email protected]', 'Paypal IPN Log', file_get_contents($filename));

スクリプトは、Paypalが投稿要求として送信したデータを電子メールで送信する必要があります。メールが届いて開くと、たくさんのデータが表示されます。私たちはそれらのほんの一握りだけが必要です、イライラしないでください。 last_namefirst_name、およびpayer_emailに相互に関係しています。

今度は受け取った投稿データを使って何かをしなければなりません。最初に投稿データを確認できます。データに問題がなく、誰もあなたを扱わないと思う場合は、次のステップを飛ばしてください。あなたのテーマがオープンソースであるために必要な投稿データを含む投稿リクエストを誰もが送信できることがわかっている場合は、投稿データを確認する必要があります。
受信したデータを確認するには、それらをPaypalに送り返す必要があります。 PaypalはVERIFIEDまたはINVALIDで答えます。次のコードスニペットは、Paypal Dev Networkからのものです。

class Paypal_IPN_API
{
//const PAYPALURI = 'ssl://www.sandbox.Paypal.com';
const PAYPALURI = 'ssl://ipnpb.Paypal.com';

private function talk_to_Paypal() {
    /*
     * Original code from Paypal Developer Network
     */

    // read the post from Paypal system and add 'cmd'
    $req = 'cmd=_notify-validate';

    foreach( $_POST as $key => $value ){

        $value = urlencode( stripslashes( $value ) );
        $req .= "&$key=$value";

    }

    // post back to Paypal system to validate
    $header  = "POST /cgi-bin/webscr HTTP/1.0\r\n";
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $header .= "Content-Length: " . strlen( $req ) . "\r\n\r\n";

    $fp = fsockopen( self::PAYPALURI, 443, $errno, $errstr, 30 );

    /*
     * End Paypal Developer Code
     */
  }
}

このコードスニペットは私が使ったクラスのものです。クラスの始めにconst PAYPALURIがあります。 Paypalはサンドボックス(アカウントが必要です)を提供しているので、あなたは '本物の'データを扱うことなくあなたのscxriptをテストすることができます。このコードはそのままにしておきます。最適化することも、fsockopen()を使用する代わりにwp_remote_get()を使用することもできます。
これでPaypalからの回答を処理する必要があります。次のスニペットは私のクラスのものです。

/*
 * Modified Paypal Developer Code
 */
if( ! $fp ){

    $this->log( "connection failed" );
    die( "Can not open connection to Paypal" );

} else {

    fputs( $fp, $header . $req );

    while( ! feof( $fp ) ){

        $res = fgets( $fp, 1024 );

        // the received data was verified by Paypal
        if( strcmp( $res, "VERIFIED" ) == 0 ){

            $payment_status = isset( $_POST['payment_status'] ) ? strtolower( $_POST['payment_status'] ) : '';

            // check payment status. only completed payments will be processed
            if( 'completed' == $payment_status ){

                // create the userdata-array
                $udata = array(
                    'payer_email'   => $_POST['payer_email'],
                    'first_name'    => $_POST['first_name'],
                    'last_name'     => $_POST['last_name']
                );

                $this->modify_wp_user( $udata );
            }

        // the received data could not be verified by Paypal
        } elseif( strcmp( $res, "INVALID" ) == 0 ){

                $this->log( "invalid request" );
                die( "Invalid request at Paypal" );

        } else {
            // something went terrible wrong
            $this->log( "unknown error while connection" );

        }
    }
}

// be Nice. close the connections you have opened
fclose( $fp );

/*
 * End modified Paypal Code
 */

静かな接続が成功したかどうかを確認してください。もしそうなら、答えを確認してください。答えがINVALIDの場合、何もしません。 VERIFIEDの場合は、最初の投稿要求から支払人の姓名と電子メールアドレスを取得します。

ユーザーの作成または更新

これで、名前とメールアドレスがわかりました。ユーザーを作成したり、既存のユーザーを更新したりできます。基本的にあなたは与えられたデータを持つユーザーを見つける必要があります。既存のユーザーがいる場合は、そのユーザーを更新します。そうでない場合は、新しいユーザーを作成します。
姓名でユーザーを取得することは可能ですが、この記事のトピックではありません。私たちは簡単な方法で、受信したばかりの電子メールアドレスでユーザーを取得しようとします。 WordPressにはこのためのNice関数があるのでこれは簡単です:get_user_by()。上記の名前とメールアドレスを配列にコピーして、この配列をメソッドmodify_wp_user()に渡します。

/**
 * 
 * Create or modify the WP-user
 * If the user already exists, the method will upgrade the user
 * to a higher user-role.
 * If the user does not exists, the method create an user with
 * the email as user-name, first and last name and the predefined
 * user-role. The password should be send via email to the user! 
 * 
 * @param array $userdata Array with the user-email, first and last name.
 * @access private
 * @since 0.1
 */
private function modify_wp_user( $userdata = array() ) {

    if( empty( $userdata ) )
        return FALSE;
    else
        extract( $userdata );

    $user = get_user_by( 'email', $userdata['payer_email'] );

    if ( ! $user ) {
        $random_password = wp_generate_password( $length=12, $include_standard_special_chars=false );

        $data = array(
            'user_pass'     => $random_password,
            'user_login'    => $payer_email,
            'user_email'    => $payer_email,
            'first_name'    => $first_name,
            'last_name'     => $last_name,
            'role'          => 'subscriber' // adjust the role to your needs
        );

        wp_insert_user( $data );
    } else {
        $data = array(
            'ID'    => $user->ID,
            'role'  => 'contributor' // adjust the role to your needs, maybe use a custom role
        );

        wp_update_user( $data );
    }
}

シンプルなスイッチです。ユーザーを取得して更新または作成します。このソリューションでは、支払人はPaypalとブログで同じEメールアドレスを使用する必要があります。そして、新しいユーザーが作成されると、ログインは電子メールアドレスと同じになります(Paypalによる送信から)。

APIエンドポイント

わかりました、私達は今Paypalへのインターフェイスを得ました。支払人が支払う場合、Paypalは私達に郵便依頼と共にデータを送ります。そして、私たちはデータを使って作業することができます(それらを検証し、新しいユーザーを作成し、あるいは既存のものを更新します)。
次の問題は最大の問題かもしれません。 Paypalがデータを送信する先のエンドポイントを作成する必要があります。 IPN handler URLを覚えてる?そして、私が最初に投稿した最初のスクリプトを覚えていますか?
今度はhttp://customer-website.tld/paypalapiのようなエンドポイントを作成する必要があります。このエンドポイントはIPNハンドラのURLです。あなたはWordPressの機能でこれを行うことができます、このトピックに関するWPSEに関するいくつかの 良い答えがあります 。ここでは説明しません。
エンドポイントを作成してそれをphpファイルにポイントしたら、最初のスクリプトをテストに使用します。このようにして、エンドポイントが機能しているかどうか、必要なデータが存在するかどうかを簡単にテストできます。
あなたのエンドポイントが動作していて必要なデータを受け取ったら、スクリプトを上記の2つの方法に置き換えてください。ただし、サンドボックスのURLを「ライブの」URLの代わりに使用してください。今すぐあなたのPaypal開発者アカウントにログインして、いくつかの支払いを作成してください。サンドボックスURLを使用すると、優れた開発環境とテスト環境が得られます。

まとめ

  • サンプルスクリプトやsandoxなどにアクセスするには、まずPayPalsデベロッパーネットワークに登録する必要があります。
  • Paypalからの投稿要求が到着したかどうかをテストするスクリプトを作成します。いくつかのIPNシミュレーションのテストを始めます。
  • Paypalから送信されたデータに基づいてWordPressユーザーを登録または更新するためのスクリプトを作成します。
  • Paypal IPN送信リクエストのターゲットとしてエンドポイントを作成します
  • まとめて、Paypalサンドボックスでテストします。
4
Ralf912