In this tutorial, we will walk through the process of integrating PayPal payments into a Laravel application. This will include setting up the PayPal button on the frontend, handling payment authorization and capturing on the server, and updating the user’s wallet balance. By the end of this guide, you’ll have a working PayPal payment system seamlessly integrated into your Laravel application.
Prerequisites
Before we start, make sure you have the following:
- A Laravel application set up
- A PayPal developer account
- Basic knowledge of JavaScript and PHP
Step 1: Setting Up PayPal SDK
First, we need to include the PayPal JavaScript SDK in our Blade File. You can include it directly from PayPal’s CDN.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PayPal Integration</title>
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID"></script>
</head>
<body>
<div class="w-100 text-right" id="paypal_button_container">
<div id="paypal-button"></div>
</div>
<input type="text" id="amount" placeholder="Enter amount" />
<div id="amount_validation_status"></div>
<div id="payment_success_alert" class="d-none">Payment successful!</div>
<script>
document.addEventListener('DOMContentLoaded', (event) => {
paypal.Buttons({
env: 'sandbox', // Or 'production'
style: {
size: 'medium',
color: 'gold',
shape: 'pill',
label: 'pay',
tagline: false
},
onCancel: function (data) {
// Show a cancel page, or return to cart
},
createOrder: function(data, actions) {
let amount = document.getElementById("amount").value;
if (amount < 10) {
document.getElementById('amount_validation_status').innerText = 'Deposit amount should be greater than $10.';
return actions.reject();
}
return actions.order.create({
purchase_units: [{
amount: {
value: amount
}
}]
});
},
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
console.log(details); // Log the entire details object to inspect its structure
// Extract necessary information
let payer = details.payer;
let transaction = details.purchase_units[0].payments.captures[0];
// Log extracted details for debugging
console.log('Payer:', payer);
console.log('Transaction:', transaction);
// Prepare data for server-side request
let invoice_id = transaction.id; // Assuming transaction ID as invoice_id
let top_up_amount = transaction.amount.value;
let payer_email = payer.email_address;
let payer_first_name = payer.name.given_name;
let payer_last_name = payer.name.surname;
let payee_email = details.purchase_units[0].payee.email_address;
let transaction_date_time = transaction.update_time;
return fetch("{{ route('wallet.payment.execute') }}", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
body: JSON.stringify({
paymentID: transaction.id,
payerID: payer.payer_id,
invoice_id: invoice_id,
top_up_amount: top_up_amount,
payer_email: payer_email,
payer_first_name: payer_first_name,
payer_last_name: payer_last_name,
payee_email: payee_email,
transaction_date_time: transaction_date_time
})
}).then(response => {
console.log('Server Response:', response);
return response.json();
}).then(response => {
if (response.success) {
document.getElementById("amount").classList.remove("is-valid");
document.getElementById("amount").value = null;
document.getElementById("payment_success_alert").classList.remove("d-none");
setTimeout(function() {
window.location.href = "{{ route('advertiser.wallet.index') }}";
}, 2000);
} else {
alert("Payment update failed.");
}
}).catch(error => {
console.error('Error:', error);
alert("Payment failed. Something went wrong.");
});
});
},
onError: function (err) {
console.error('PayPal Error:', err);
alert("Payment failed. Something went wrong.");
}
}).render('#paypal-button');
});
</script>
</body>
</html>
Explanation
- PayPal SDK Script: The script tag loads the PayPal SDK.
- PayPal Buttons: Initializes and renders the PayPal buttons.
- Order Creation: Validates the amount and creates an order.
- Order Approval: Captures the payment and sends the necessary data to the server for further processing.
Step 2: Server-Side Handling in Laravel
In your Laravel controller, create a method to handle the payment execution. This method will update the user’s wallet and save the transaction details.
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use App\Models\WalletTopUpHistory;
use App\Mail\AdvertiserDeposit;
public function executePayment(Request $request) {
DB::beginTransaction();
try {
$top_up_amount = $request->top_up_amount;
$user = Auth::user();
$user->wallet = $user->wallet + $top_up_amount;
$user->save();
$transaction_date_time = date("Y-m-d H:i:s", strtotime($request->transaction_date_time));
$wallet_top_up_history = new WalletTopUpHistory();
$wallet_top_up_history->advertiser_id = Auth::id();
$wallet_top_up_history->invoice_id = $request->invoice_id;
$wallet_top_up_history->top_up_amount = $request->top_up_amount;
$wallet_top_up_history->payer_email = $request->payer_email;
$wallet_top_up_history->payer_first_name = $request->payer_first_name;
$wallet_top_up_history->payer_last_name = $request->payer_last_name;
$wallet_top_up_history->payee_email = $request->payee_email;
$wallet_top_up_history->transaction_date_time = $transaction_date_time;
$wallet_top_up_history->save();
$email = $user->email;
$amount = $request->top_up_amount;
Mail::to($email)->send(new AdvertiserDeposit("emails.advertiser.deposit", $amount, $user));
DB::commit();
return response()->json(['success' => true]);
} catch (\Exception $e) {
DB::rollBack();
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
}
}
Explanation
- Transaction Management: Wraps the operations in a database transaction to ensure data integrity.
- Wallet Update: Updates the user’s wallet balance.
- Transaction History: Saves the transaction details in
WalletTopUpHistory
. - Email Notification: Sends a confirmation email to the user.
- Error Handling: Rolls back the transaction in case of any errors and returns a JSON response
Conclusion
Integrating PayPal payments into your Laravel application involves setting up the PayPal SDK on the frontend and handling the payment processing on the backend. By following this guide, you can seamlessly integrate PayPal payments and provide a smooth experience for your users.
Read More laravel