使用PayPal REST API为循环中的成员充电

时间:2013-07-24 12:03:49

标签: php api rest paypal

我想每周向网站会员收费。我已将他们的信用卡信息与他们的地址,电话号码,城市,州等存储在一个表格中。

我正在使用PayPal REST API和PHP。

这是我的代码:

while ($row2 = $res2->fetch_assoc ())
{                   
    // ### Address
    // Base Address object used as shipping or billing
    // address in a payment. [Optional]
    $addr = new Address ();

    if ($row2 ['billing_address'])
        $addr->setLine1 ($row2 ['billing_address']);

    if ($row2 ['billing_address2'])
        $addr->setLine2 ($row2 ['billing_address2']);

    if ($row2 ['billing_city'])
        $addr->setCity ($row2 ['billing_city']);

    if ($row2 ['billing_state'])
        $addr->setState ($row2 ['billing_state']);

    if ($row2 ['billing_zip'])
        $addr->setPostal_code ($row2 ['billing_zip']);

    $addr->setCountry_code ("US");

    if ($row2 ['billing_phone'])
        $addr->setPhone ($row2 ['billing_phone']);

    // Decrypt Credit Cart #
    $credit_card_number = decrypt ($row2 ['cc_number'], 'hassan');
    $cc_name_array = explode (" ", $row2 ['cc_name']);
    $cc_name_array_count = count ($cc_name_array);

    $cc_f_name = $cc_name_array [0];
    $cc_l_name = "";
    for ($i = 1; $i < $cc_name_array_count; $i++)
    {
        $cc_l_name .= str_replace (array ("&", "."), "", $cc_name_array [$i]) . " ";
    }
    $cc_l_name = trim ($cc_l_name);

    // ### CreditCard
    // A resource representing a credit card that can be
    // used to fund a payment.
    $card = new CreditCard ();
    if (strtolower ($row2 ['cc_type']) == "visa")
    {
        $card->setType ('visa');
    }
    elseif (strtolower ($row2 ['cc_type']) == "mastercard")
    {
        $card->setType ('mastercard');
    }
    elseif (strtolower ($row2 ['cc_type']) == "discover cards")
    {
        $card->setType ('discover');
    }
    elseif (strtolower ($row2 ['cc_type']) == "american express")
    {
        $card->setType ('amex');
    }
    $card->setNumber ($credit_card_number);
    $card->setExpire_month ($row2 ['cc_expiry_month']);
    $card->setExpire_year ($row2 ['cc_expiry_year']);
    $card->setCvv2 ($row2 ['cc_cvv']);
    $card->setFirst_name ($cc_f_name);
    $card->setLast_name ($cc_l_name);
    $card->setBilling_address ($addr);

    // ### FundingInstrument
    // A resource representing a Payer's funding instrument.
    // Use a Payer ID (A unique identifier of the payer generated
    // and provided by the facilitator. This is required when
    // creating or using a tokenized funding instrument)
    // and the `CreditCardDetails`
    $fi = new FundingInstrument ();
    $fi->setCredit_card ($card);

    // ### Payer
    // A resource representing a Payer that funds a payment
    // Use the List of `FundingInstrument` and the Payment Method
    // as 'credit_card'
    $payer = new Payer ();
    $payer->setPayment_method ("credit_card");
    $payer->setFunding_instruments (array ($fi));

    // ### Amount
    // Let's you specify a payment amount.
    $amount = new Amount ();
    $amount->setCurrency ("USD");
    //$amount->setTotal ("1.00");
    $amount->setTotal ($row ['billing_cost']);

    // ### Transaction
    // A transaction defines the contract of a
    // payment - what is the payment for and who
    // is fulfilling it. Transaction is created with
    // a `Payee` and `Amount` types
    $transaction = new Transaction ();
    $transaction->setAmount ($amount);
    $transaction->setDescription ("Commission deducted for the sold property.");

    // ### Payment
    // A Payment Resource; create one using
    // the above types and intent as 'sale'
    $payment = new Payment ();
    $payment->setIntent ("sale");
    $payment->setPayer ($payer);
    $payment->setTransactions (array ($transaction));



    // ### Create Payment
    // Create a payment by posting to the APIService
    // using a valid ApiContext (See bootstrap.php for more on `ApiContext`)
    // The return object contains the status;
    try
    {
        $payment->create ($apiContext);
    }
    catch (\PPConnectionException $ex)
    {
        echo "Exception: " . $ex->getMessage () . PHP_EOL;
        var_dump ($ex->getData());
        exit (1);
    }


    if ($payment->getId ())
    {
        $br_date = time ();
        $insert = "INSERT INTO `billing_reports`
                    (`sh_id`, `listing_id`, `billed_person_type`, `billed_person_id`, `cc_type`, `cc_name`, `cc_number`, `cc_expiry_month`, `cc_expiry_year`, `cc_cvv`, `billing_amount`, `payment_id`, `br_date`, `status`)
                    VALUES ('" . $row ['sh_id'] . "', '" . $row ['listing_id'] . "', '" . $row2 ['member_type'] . "', '" . $row2 ['member_id'] . "', '" . $row2 ['cc_type'] . "', '" . $row2 ['cc_name'] . "', '" . $row2 ['cc_number'] . "', '" . $row2 ['cc_expiry_month'] . "', '" . $row2 ['cc_expiry_year'] . "', '" . $row2 ['cc_cvv'] . "', '" . $row ['billing_cost'] . "', '" . $payment->getId () . "', '" . $br_date . "', 1)";
        $GLOBALS ['mysqli']->query ($insert) or die ($GLOBALS ['mysqli']->error . __LINE__);
        //unset ($addr, $card, $fi, $payer, $amount, $transaction, $payment);
    }
}

循环的每次迭代都从表中获取一个新成员,并将其信息填充到REST API变量中。

但问题是,如果2个或更多连续成员具有相同的信用卡信息,则此循环可正常工作。当信息被更改时,事务不会通过。

我不是PayPal的专家。因此,需要你们的帮助。我认为问题在于$ payment对象。它没有使用新值进行实例化。任何形式的帮助都会很棒。我已经花了3天时间:(

1 个答案:

答案 0 :(得分:0)

实际上问题是循环'$ apiContext'对象在后续迭代中丢失了它的值。因此,简单快速的修复(不确定它是否是正确的修复)是在每次迭代中初始化'$ apiContext'。像这样......

while ($row = $res->fetch_assoc ())
{

    // ### Api Context
    // Pass in a `PayPal\Rest\ApiContext` object to authenticate 
    // the call. You can also send a unique request id 
    // (that ensures idempotency). The SDK generates
    // a request id if you do not pass one explicitly. 
    $apiContext = new ApiContext(new OAuthTokenCredential(
            '<client-id>',
            '<secret>'));

这样,当执行以下代码行时,'$ apiContext'对象将具有值。

$payment->create ($apiContext);

最初'$ apiContext'对象在'bootstrap.php'文件中初始化。它是一次初始化。从理论上讲,这应该适用于所有循环迭代,但它不起作用。要访问“ApiContext”类,您还需要在顶部包含以下代码行。

use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;