Reputation: 5386
I have created single batch payout using their documentation. so that I can send money to seller.
But I don't know what I should do after it. How can I show a payment form, where user can login in PayPal and pay the amount?
This is my code in controller function
public function payViaPaypal(){
$payouts = new \PayPal\Api\Payout();
$senderBatchHeader = new \PayPal\Api\PayoutSenderBatchHeader();
$senderBatchHeader->setSenderBatchId(uniqid('invoice-1qaqw23wdwdwew').microtime('true'))
->setEmailSubject("You have a Payout!");
$senderItem = new \PayPal\Api\PayoutItem();
$senderItem->setRecipientType('Email')
->setNote('Thanks for your patronage!')
->setReceiver('[email protected]')
->setSenderItemId(uniqid().microtime('true'))
->setAmount(new \PayPal\Api\Currency('{
"value":"1.0",
"currency":"USD"
}'));
$payouts->setSenderBatchHeader($senderBatchHeader)
->addItem($senderItem);
$request = clone $payouts;
$redirect_url = null;
try {
$output = $payouts->create(null, $this->api_context);
} catch (\Exception $e) {
dd('here',$this->errorDetails($e));
}
// dd("Created Single Synchronous Payout", "Payout", $output->getBatchHeader()->getPayoutBatchId(), $request, $output);
$redirect_url = null;
foreach($output->getLinks() as $link) {
if($link->getRel() == 'self') {
$redirect_url = $link->getHref();
break;
}
}
return $output;
}
when I hit route to access this code and I receive this json response.
{ "batch_header": { "payout_batch_id": "79CTFV2X5TS58", "batch_status": "PENDING", "sender_batch_header": { "sender_batch_id": "invoice-1qaqw23wdwdwew5f0f5003612091594839043.3978", "email_subject": "You have a Payout!" } }, "links": [ { "href": "https://api.sandbox.paypal.com/v1/payments/payouts/79CTFV2X5TS58", "rel": "self", "method": "GET", "enctype": "application/json" } ] }
I am expecting that user will be taken to PayPal payment page where user will login and pay amount after that PayPal will inform me about the payment.
But I have tried to find the solution over internet but no example/solution I can find.
Upvotes: 0
Views: 2882
Reputation: 5386
I was using wrong approach.
Solution is to create a payment object and add payee (who will receive payment as seller) email address in it.
There are two functions required.
1 to create payment object 2 to get payment details from paypal using API and then execute this payment so that amount can be transferred to receipeint account.
3 Routes are required for following
Here is full code example
Routes
create payment object
Route::get('/invoices/process-payment','Vendor\PayPalController@processPaymentInvoiceViaCheckout');
when payment object is created then get its details and execute payment to send money.
Route::get('/invoices/response-success','Vendor\PayPalController@paypalResponseSuccess');
when cancel to pay
Route::get('/invoices/response-cancel','Vendor\PayPalController@paypalResponseCancel');
Controller
<?php
namespace App\Http\Controllers\Vendor;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payee;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Transaction;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Exception\PayPalConnectionException;
use PayPal\Rest\ApiContext;
use PHPUnit\TextUI\ResultPrinter;
class PayPalController extends Controller
{
private $api_context;
public function __construct()
{
$this->api_context = new ApiContext(
new OAuthTokenCredential(config('paypal.client_id'), config('paypal.secret'))
);
$this->api_context->setConfig(config('paypal.settings'));
}
public function processPaymentInvoiceViaCheckout(){
$payer = new Payer();
$payer->setPaymentMethod("paypal");
$item1 = new Item();
$item1->setName('Ground Coffee 40 oz')
->setCurrency('USD')
->setQuantity(1)
// ->setSku("123123") // Similar to `item_number` in Classic API
->setPrice(7.5);
$item2 = new Item();
$item2->setName('Granola bars')
->setCurrency('USD')
->setQuantity(5)
// ->setSku("321321") // Similar to `item_number` in Classic API
->setPrice(2);
$itemList = new ItemList();
$itemList->setItems(array($item1, $item2));
$details = new Details();
$details->setShipping(1.2)
->setTax(1.3)
->setSubtotal(17.50);
$amount = new Amount();
$amount->setCurrency("USD")
->setTotal(20)
->setDetails($details);
$payee = new Payee();
//this is the email id of the seller who will receive this amount
$payee->setEmail("[email protected]");
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($itemList)
->setDescription("Payment description")
->setPayee($payee)
->setInvoiceNumber(uniqid());
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl(url('/invoices/response-success'))
->setCancelUrl(url('/invoices/response-cancel'));
$payment = new Payment();
$payment->setIntent("sale")
->setPayer($payer)
->setRedirectUrls($redirectUrls)
->setTransactions(array($transaction));
$request = clone $payment;
try {
//create payment object
$createdPayment = $payment->create($this->api_context);
//get payment details to get payer id so that payment can be executed and transferred to seller.
$paymentDetails = Payment::get($createdPayment->getId(), $this->api_context);
$execution = new PaymentExecution();
$execution->setPayerId($paymentDetails->getPayer());
$paymentResult = $paymentDetails->execute($execution,$this->api_context);
} catch (\Exception $ex) {
//handle exception here
}
//Get redirect url
//The API response provides the url that you must redirect the buyer to. Retrieve the url from the $payment->getApprovalLink() method
$approvalUrl = $payment->getApprovalLink();
return redirect($approvalUrl);
}
public function paypalResponseCancel(Request $request)
{
//normally you will just redirect back customer to platform
return redirect('invoices')->with('error','You can cancelled payment');
}
public function paypalResponseSuccess(Request $request)
{
if (empty($request->query('paymentId')) || empty($request->query('PayerID')) || empty($request->query('token'))){
//payment was unsuccessful
//send failure response to customer
}
$payment = Payment::get($request->query('paymentId'), $this->api_context);
$execution = new PaymentExecution();
$execution->setPayerId($request->query('PayerID'));
// Then we execute the payment.
$result = $payment->execute($execution, $this->api_context);
dd($request->all(),$result);
//payment is received, send response to customer that payment is made.
}
}
You can read this official example as well
Upvotes: 0
Reputation: 30379
Payouts is for sending money from your account to another account. There is no form to show or log into. You are the API caller, and payments are automatically approved as coming from your account.
If you want a form for a user to approve paying from their account to some other account, use invoicing: https://developer.paypal.com/docs/invoicing/
Alternatively, maybe you don't need an invoice form but just a regular PayPal Checkout with a 'payee' recipient set: https://developer.paypal.com/docs/checkout/integration-features/custom-payee/
Upvotes: 2