0

私はDrupal 7で作業しており、ユーザーがpaypalで支払うことで登録することになっている1つの場所でコーディングしてpaypalを実装しました。戻ってきたときに、支払いが確認された場合はコールバック関数に登録する必要があります。私のコールバック関数は単に機能していません & コールバックで取得すると思われるすべての変数値も false を返します...

ここに私のコードがあります -

これは、ユーザーを値とともにペイパルに送信するために使用しています--

function user_type_register_form_submit($form, &$form_state){
  global $base_url;
  $username = $form_state['values']['name'];
  $user_email = $form_state['values']['mail'];
  $user_type = $form_state['values']['user_type'];
  $user_first_name = $form_state['values']['field_first_name']['und'][0]['value'];
  $user_last_name = $form_state['values']['field_last_name']['und'][0]['value'];
  $user_company_name = $form_state['values']['field_company_name']['und'][0]['value'];
  $user_address_line_1 = $form_state['values']['field_address_line_1']['und'][0]['value'];
  $user_address_line_2 = $form_state['values']['field_address_line_2']['und'][0]['value'];
  $user_city = $form_state['values']['field_user_city']['und'][0]['value'];
  $user_state = $form_state['values']['field_user_state']['und'][0]['value'];
  $user_zip = $form_state['values']['field_user_zip']['und'][0]['value'];
  $user_phone_number = $form_state['values']['field_phone_number_']['und'][0]['value'];
  $user_mobile_number = $form_state['values']['field_mobile_number_']['und'][0]['value'];
  $user_fax_number = $form_state['values']['field_fax_number_']['und'][0]['value'];

  $paypal = array();
  $paypal['cmd'] = '_xclick';
  $paypal['business'] = 'rajeev_1359782736_biz@gmail.com';
  $paypal['page_style'] = 'Primary';
  $paypal['bn'] = 'PP-DonationsBF';
  $paypal['item_name'] = 'Membership';
  $paypal['currency_code'] = 'USD';
  $paypal['no_shipping'] = '1';
  $paypal['tax'] = '0';
  $paypal['lc'] = 'US';
  $paypal['rm'] = '1';
  $paypal['return'] = $base_url.'/?q=paypal/payment';
  $paypal['cancel_return'] = $base_url.'/?q=user/register';      
  $paypal['uname'] = $username;
  $paypal['email'] = $user_email;
  $paypal['user_type'] = $user_type;
  $paypal['first_name'] = $user_first_name;
  $paypal['last_name'] = $user_last_name;
  $paypal['comp_name'] = $user_company_name;
  $paypal['address1'] = $user_address_line_1;
  $paypal['address2'] = $user_address_line_2;
  $paypal['city'] = $user_city;
  $paypal['state'] = $user_state;
  $paypal['zip'] = $user_zip;
  $paypal['phone'] = $user_phone_number;
  $paypal['mobile'] = $user_mobile_number;
  $paypal['fax'] = $user_fax_number;
  switch($user_type){    
    case '0':
      dpm("General");
      $membership_price = 50;
      $paypal['amount'] = $membership_price;
      $paypal['item_number'] = 1;

      $query = http_build_query($paypal, '', '&');

      $form_state['redirect'] = 'https://www.sandbox.paypal.com/cgi-bin/webscr?' .$query;

      break;

    case '1':
      dpm("Student");
      $membership_price = 50;
      $paypal['amount'] = $membership_price;
      $paypal['item_number'] = 2;

      $query = http_build_query($paypal, '', '&');

      $form_state['redirect'] = 'https://www.sandbox.paypal.com/cgi-bin/webscr?' .$query;
      break;

    case '2':
      dpm("Government");
      $membership_price = 50;      
      $paypal['amount'] = $membership_price;
      $paypal['item_number'] = 3;

      $query = http_build_query($paypal, '', '&');

      $form_state['redirect'] = 'https://www.sandbox.paypal.com/cgi-bin/webscr?' .$query;
      break;
  }
}

ユーザーをペイパルに送信するクエリをデバッグしましたが、次のようになります-

cmd=_xclick&business=rajeev_1359782736_biz%40gmail.com&page_style=Primary&bn=PP-DonationsBF&item_name=Membership&currency_code=USD&no_shipping=1&tax=0&lc=US&rm=1&return=http%3A%2F%2Fctaep-test.kr001.us%2F%3Fq%3Dpaypal%2Fpayment&cancel_return=http%3A%2F%2Fctaep-test.kr001.us%2F%3Fq%3Duser%2Fregister&uname=admin_list&email=rajeevkr.dei%40gmail.com&user_type=0&first_name=Rajeev&last_name=Kumar&comp_name=&address1=sector+27&address2=&city=noida&state=ky&zip=201301&phone=9650361380&mobile=&fax=&amount=50&item_number=1

コールバックを受信するために使用しているこの関数 -

function paypal_payment_paypal_ipn_callback($vars = array()){

  header("Content-type: text/html");
  header("Expires: Wed, 29 Jan 1975 04:15:00 GMT");
  header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  header("Cache-Control: no-cache, must-revalidate");
  header("Pragma: no-cache");

  watchdog('paypal', '1');

  // 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";
  }

  watchdog('paypal', '2');

  // post back to PayPal system to validate
  $header = '';
  $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
  $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
  $header .= "Host: www.sandbox.paypal.com\r\n";
  $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
  $fp =  fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

  //Added - new
  // reading posted data from directly from $_POST causes serialization 
  // issues with array data in POST
  // reading raw POST data from input stream instead. 
  $raw_post_data = file_get_contents('php://input');
  $raw_post_array = explode('&', $raw_post_data);
  $myPost = array();
  foreach ($raw_post_array as $keyval) {
    $keyval = explode ('=', $keyval);
    if (count($keyval) == 2)
      $myPost[$keyval[0]] = urldecode($keyval[1]);
  }
  // read the post from PayPal system and add 'cmd'
  $req = 'cmd=_notify-validate';
  if(function_exists('get_magic_quotes_gpc')) {
    $get_magic_quotes_exists = true;
  } 
  foreach ($myPost as $key => $value) {        
    if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { 
        $value = urlencode(stripslashes($value)); 
    } else {
        $value = urlencode($value);
    }
    $req .= "&$key=$value";
  }


  // STEP 2: Post IPN data back to paypal to validate

  $ch = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr');
  curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));

  // In wamp like environments that do not come bundled with root authority certificates,
  // please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path 
  // of the certificate as shown below.
  // curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
  if( !($res = curl_exec($ch)) ) {
    // error_log("Got " . curl_error($ch) . " when processing IPN data");
    curl_close($ch);
    exit;
  }
  curl_close($ch);

  //Added end

  if (!$fp) {
    watchdog('paypal', 'HTTP error');
  } else {
    fputs ($fp, $header . $req);
    watchdog('paypal', $header . $req);

    while (!feof($fp)) {
      $res = fgets ($fp, 1024);

      watchdog('paypal', '3');
      //dpm($res);
      watchdog('pay_status',$res);      
      if (strcmp ($res, "VERIFIED") == 0) {
      //if (strcmp ($res, "INVALID") == 0) {
        // assign posted variables to local variables
        //$txn_id = $_POST['txn_id'];
        watchdog('paypal', '4');

        //Information about you:
        $receiver_email = $_POST['business'];

        //Information about the transaction:
        $item_name = $_POST['item_name'];
        $item_number = $_POST['item_number'];
        $payment_status = $_POST['payment_status'];
        $payment_amount = $_POST['mc_gross'];
        $payment_currency = $_POST['mc_currency'];
        $txn_id = $_POST['txn_id'];
        $receiver_email = $_POST['receiver_email'];
        $payer_email = $_POST['payer_email'];

        dpm($receiver_email);

        //Information about your buyer:
        $user_email = $_POST['email'];
        $user_name = $_POST['uname'];
        $first_name = $_POST['first_name'];
        $last_name = $_POST['last_name'];
        $company_name = $_POST['comp_name'];
        $address_address_line_1 = $_POST['address1'];
        $address_address_line_2 = $_POST['address2'];
        $address_city = $_POST['city'];
        $address_state = $_POST['state'];
        $address_zip = $_POST['zip'];
        $user_phone = $_POST['phone'];
        $user_mobile = $_POST['mobile'];
        $user_fax = $_POST['fax'];

        //Information about the payment:
        $membership_type = $_POST['item_name'];

        //Other information about the transaction:

        //watchdog('paypal', '4');

        // check the payment_status is Completed
        // check that txn_id has not been previously processed
        // check that receiver_email is your Primary PayPal email
        // check that payment_amount/payment_currency are correct
        // process payment
        $password = user_password(8);
        $fields = array(
          'name' => $user_name,
          'mail' => $user_email,
          'pass' => $password,
          'status' => 1,
          'init' => $user_email,
          'roles' => array(
            DRUPAL_AUTHENTICATED_RID => $membership_type,),
        );
       // user_save('', $fields);
      $account = user_save('', $fields);
      dpm("user registered");
      }
      else if (stripos($res, "VERIFIED") !== false) {
        watchdog('paypal', 'INVALID');
        // log for manual investigation
      }
    }
    fclose ($fp);
  }
  return 'Callback Complete';
}

これが私のウォッチドッグエラーです -

inside-callback : 1
Notice: Undefined index: item_name in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: item_number in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: payment_status in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: mc_gross in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: mc_currency in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: txn_id in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: receiver_email in paypal_payment_paypal_ipn_callback()
Notice: Undefined index: payer_email in paypal_payment_paypal_ipn_callback()
inside-invalid : 4
4

2 に答える 2

3

PayPal は HTTP1.0 のサポートを 2013 年 5 月 1 日まで延長しましたが、HTTP1.1 サポートのみのためにサンドボックスを既に更新している可能性があります。

https://www.x.com/content/bulletin-ipn-and-pdt-scripts-and-http-1-1

これが当てはまる場合は、次のようにコールバック スクリプトを更新する必要があります。

// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.1\r\n"; // HTTP1.1 Update
$header .= "Content-Length: " . strlen($req) . "\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Host: www.sandbox.paypal.com\r\n"; // Sandbox Host
//$header .= "Host: ipnpb.paypal.com\r\n"; // Live Host
$header .= "Connection: close\r\n\r\n";

さらなる互換性のために

https://ppmts.custhelp.com/app/answers/detail/a_id/926/

1) PHP スクリプトは、IPN 検証応答もトリムする必要があります。

スクリプトを変更します。

//From:
if (strcmp ($res, "VERIFIED") == 0) {
..
else if (strcmp ($res, "INVALID") == 0) {

//To:
if (strcmp (trim($res), "VERIFIED") == 0) {
..
else if (strcmp (trim($res), "INVALID") == 0) {

2) PHP では、ヘッダーの最後の行に二重の行末マーカーが含まれていることを確認してください: \r\n\r\n 上記の例のように: $header .="Connection: close\r\n\r\ n";

3) PHP で、ヘッダーで宣言されている同じホストへのソケット接続を開いていることを確認します。ヘッダーがホストを次のように宣言しているため

$header .="Host: ipnpb.paypal.com\r\n";

同じホストへの接続を開く必要があります。

$fp = fsockopen ('ssl://ipnpb.paypal.com', 443, $errno, $errstr, 30);
于 2013-02-05T07:07:55.043 に答える
0

問題はここにあります:

$paypal['return'] = $base_url.'/?q=paypal/payment';

そこで定義したのは、ユーザーが支払いを行った後にどこにたどり着くかです。また、PDT を有効にしない限り、トランザクション ID も渡されません。

notify_urlを使用して IPN ハンドラを登録する必要があります。

$paypal['notify_url'] = $base_url.'/?q=paypal/payment';
于 2013-02-05T08:54:17.470 に答える