我想每周向网站会员收费。我已将他们的信用卡信息与他们的地址,电话号码,城市,州等存储在一个表格中。
我正在使用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天时间:(
答案 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;