API PayPal с Laravel - Обновление данных

Я пытаюсь реализовать API PayPal payment с помощью Laravel 5.1. Но когда я вхожу в PayPal (sandbox), он использует адрес, который я использовал в своей учетной записи, а также использует имя из учетной записи PayPal, а не данные с моего сайта. Это моя проблема.

Я хочу использовать данные с моего сайта, потому что это не имеет смысла, если я ввожу адрес доставки (например) с моего сайта и не использую его. Пожалуйста, посмотрите мой код ниже для справки (или прокомментируйте ниже некоторые подробности от меня).

class PaypalPaymentController extends BaseController
{

    private $_api_context;

    public function __construct(){
        $paypal_conf = \Config::get('paypal');

        $this->_api_context = new ApiContext(new OAuthTokenCredential(
            $paypal_conf['client_id'],
            $paypal_conf['secret']
        ));

        $this->_api_context->setConfig($paypal_conf['settings']);
    }

    public function payWithPaypal(Request $request){
        $payer = new Payer;
        $payer->setPaymentMethod('paypal');

        $price = 0;

        switch($request->get('amount')) {
            case '10 books':
                $price = 6200;
                break;
            case '20 books':
                $price = 12200;
                break;
            case '50 books':
                $price = 25200;
                break;
            default:
                return redirect()
                        ->route('bookstore.shipping')
                        ->with('danger', 'Please select the right amount of book/s.');
                break;
        }

        $item1 = new Item();
        $item1->setName($request->get('amount'))
                ->setCurrency('PHP')
                ->setQuantity(1)
                ->setPrice($price);

        $item_list = new ItemList();
        $item_list->setItems([$item1]);

        $amount = new Amount();
        $amount->setCurrency('PHP')
                ->setTotal($price);

        $transaction = new Transaction();
        $transaction->setAmount($amount)
                    ->setItemList($item_list)
                    ->setDescription('Books transaction');

        $redirect_urls = new RedirectUrls();
        $redirect_urls->setReturnUrl(route('bookstore.payment-status'))
                        ->setCancelUrl(route('bookstore.payment-status'));

        $payment = new Payment();
        $payment->setIntent('Sale')
                ->setPayer($payer)
                ->setRedirectUrls($redirect_urls)
                ->setTransactions([$transaction]);

         $patchReplace = new Patch();
         $patchReplace->setOp('add')
                    ->setPath('/transactions/0/item_list/shipping_address')
                    ->setValue(json_decode('{
                        "line1": "345 Lark Ave",
                        "city": "Montreal",
                        "state": "QC",
                        "postal_code": "H1A4K2",
                        "country_code": "CA"
                    }'));

         $patchRequest = (new PatchRequest())->setPatches([$patchReplace]);


        try{

            $payment->create($this->_api_context);
            $payment->update($patchRequest, $this->_api_context);

        } catch(\Palpal\Exception\PPConnectionException $e){

            if(\Config::get('app.debug')){
                return redirect()
                        ->route('bookstore.shipping')
                        ->with('danger', 'Connection Timeout.');
            }

            return redirect()
                    ->route('bookstore.shipping')
                    ->with('danger', 'Some error occured, sorry for the inconvenience.');
        }

        foreach($payment->getLinks() as $link){
            if($link->getRel() == 'approval_url'){
                $redirect_url = $link->getHref();
                break;
            }
        }

        Session::put('paypal_payment_id', $payment->getId());

        if(isset($redirect_url)){
            return Redirect::away($redirect_url);
        }

        return redirect()
                ->route('bookstore.shipping')
                ->with('danger', 'Unknown error occured.');
    }

    public function getPaymentStatus(){
        $payment_id = Session::get('paypal_payment_id');
        Session::forget('paypal_payment_id');

        if(empty(Input::get('PayerID')) || empty(Input::get('token'))){
            return redirect()
                    ->route('bookstore.shipping')
                    ->with('danger', 'Payment failed.');
        }

        $payment = Payment::get($payment_id, $this->_api_context);
        $execution = new PaymentExecution();
        $execution->setPayerId(Input::get('PayerID'));

        $result = $payment->execute($execution, $this->_api_context);

        if($result->getState() == 'approved'){
            // Send Email
            $email_data = [
                'number_of_books' => $payment->transactions[0]->item_list->items[0]->name,
                'shipping' => [
                    'street' => $payment->payer->payer_info->shipping_address->line1,
                    'city' => $payment->payer->payer_info->shipping_address->city,
                    'state' => $payment->payer->payer_info->shipping_address->state,
                    'country' => $payment->payer->payer_info->shipping_address->country_code,
                ]
            ];

            // Send email function here ...

            return redirect()
                    ->route('bookstore.shipping')
                    ->with('success', 'Transaction payment success!');
        }

        return redirect()
                ->route('bookstore.shipping')
                ->with('danger', 'Payment failed.');
    }

}

Я также рассмотрел эту ссылку, но похоже, что она не может ответить на мою проблему. Кроме того, what if в стране есть провинция? Как мы можем добавить это?

Обновление 1

  1. Добавлен новый класс Patch().
  2. Измененный код в Try Catch.

Примечание. accepted ответ также получит bounty плюс up.

Обновление 2 с помощью учебника

  1. Для PHP/Laravel (я в настоящее время использую v5.1), установите этот пакет paypal/rest-api-sdk-php

  2. Создайте учетную запись Sandbox в PayPal. Выберите Купить в Paypal.

  3. Продолжайте, пока не увидите параметры, выберите " Магазин мира".

  4. Войдите в систему developer.paypal.com.

  5. Нажмите " Учетные записи". Нажмите " Создать учетную запись".

  6. Выберите страну, в которой вы хотите. Выберите "Личный" (учетная запись покупателя) в "Тип учетной записи".

  7. Добавить адрес электронной почты, избегать использования -. Вместо этого используйте _.

  8. Укажите, сколько вы хотите получить PayPal Balance.

  9. Нажмите "Создать учетную запись".

Сделать это жить?

https://github.com/paypal/PayPal-PHP-SDK/wiki/Going-Live

Ответ 1

После того как вы создали платеж, попробуйте обновить адрес, как показано в этом примере.

$paymentId = $createdPayment->getId();

$patch = new \PayPal\Api\Patch();
$patch->setOp('add')
    ->setPath('/transactions/0/item_list/shipping_address')
    ->setValue([
        "recipient_name" => "Gruneberg, Anna",
        "line1" => "52 N Main St",
        "city" => "San Jose",
        "state" => "CA",
        "postal_code" => "95112",
        "country_code" => "US"
    ]);

$patchRequest = new \PayPal\Api\PatchRequest();
$patchRequest->setPatches([$patch]);
$result = $createdPayment->update($patchRequest, $apiContext);

Я также рассмотрел эту ссылку, но похоже, что она не может ответить на мою проблему. Кроме того, что, если в стране есть провинция? Как мы можем добавить это?

Используйте коды состояний, перечисленные здесь.

Ответ 2

Я не использовал API PayPal в течение длительного времени, но просто просмотр документов показывает, что поле payer_info доставки payer_info устарело (https://developer.paypal.com/docs/api/orders/v1/#definition-payer_info) и предлагает использовать адрес доставки в purchase_unit вместо этого.

Согласно Документам, это должно быть установлено в классе CartBase с помощью функции setItemList() (http://paypal.github.io/PayPal-PHP-SDK/docs/class-PayPal.Api.CartBase.html).

Изменить:

Итак, для используемого вами пакета вам нужно добавить объект PayPal\Api\ShippingAddress к переменной $item_list:

$shipping = new PayPal\Api\ShippingAddress();
$shipping->setLine1('123 1st St.')
    ->setCity('Some City')
    ->setState('CA')
    ->setPostalCode("95123")
    ->setCountryCode("US")
    ->setPhone("555-555-5555")
    ->setRecipientName("John Doe");

$item_list = new ItemList();
$item_list->setItems([$item1])
    ->setShippingAddress($shipping);

Класс ItemList ref: http://paypal.github.io/PayPal-PHP-SDK/docs/source-class-PayPal.Api.ItemList.html#74-85

Ответ 3

Я думаю, что это соответствующая документация, которую вы ищете.

Для людей, у которых уже есть учетные записи PayPal и с которыми вы уже запрашивали адрес доставки, прежде чем они захотят платить с помощью PayPal, вы можете использовать введенный адрес вместо адреса, который человек сохранил с помощью PayPal.

Вместо использования адреса, сохраненного в их учетной записи,

Плательщику показан переданный адрес, но он не может его редактировать. Не отображается адрес, если адрес недействителен, например, отсутствующие обязательные поля, такие как страна, или если адрес вообще не включен.


Изменение: попробуйте что-то подобное вместо того, что у вас есть.

$address = new ShippingAddress();
$address->setCity('Toronto');
$address->setState('ON');
$address->setCountryCode('CA');
$address->setLine1('123 Fake Street');
$address->setPostalCode('M1M1M1');

$payerInfo = new PayerInfo();
$payerInfo->setShippingAddress($address);

$payer = new Payer();
$payer->setPaymentMethod('paypal');

Ответ 4

Я не очень много работал с PayPal, но я беру это из официальной документации, поэтому я уверен, что это сработает для вас. Переопределение адресов, хранящихся в PayPal. Список доступных переменных, которые вы можете использовать на странице проверки, см. В разделе Автоматическое заполнение переменных страницы PayPal.

<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
    <!-- Enable override of buyers address stored with PayPal . -->
    <input type="hidden" name="address_override" value="1">
    <!-- Set variables that override the address stored with PayPal. -->
    <input type="hidden" name="first_name" value="John">
    <input type="hidden" name="last_name" value="Doe">
    <input type="hidden" name="address1" value="345 Lark Ave">
    <input type="hidden" name="city" value="Montreal">

    <input type="hidden" name="state" value="QC">

    <input type="hidden" name="zip" value="H1A4K2">
    <input type="hidden" name="country" value="CA">
    <input type="image" name="submit"
       src="https://www.paypalobjects.com/en_US/i/btn/btn_buynow_LG.gif"
       alt="PayPal - The safer, easier way to pay online">
</form>

Или, изнутри вашего скрипта...

$address = new ShippingAddress();
$address->setCity('Montreal');
$address->setState('QC');
$address->setCountryCode('CA');
$address->setLine1('345 Lark Ave');
$address->setPostalCode('H1A4K2');

$payerInfo = new PayerInfo();
$payerInfo->setShippingAddress($address);

Вот список доступных кодов провинций. Вы использовали бы эти двухбуквенные строки для переменной "state", как и в американском штате. Коды стран и провинций PayPal

Название провинции | Код провинции

Альберта | AB

Британская Колумбия | BC

Манитоба | MB

Новый Брансуик | NB

Ньюфаундленд и Лабрадор | NL

Северо-западные территории | NT

Новая Шотландия | NS

Нунавут | NU

Онтарио | ON

Остров Принца Эдуарда | PE

Квебек | QC

Саскачеван | SK

Юкон | YT

Я надеюсь, это поможет вам.