Subiendo proyecto completo sin restricciones de git ignore
This commit is contained in:
134
vendor/kingflamez/laravelrave/docs/verification/callback.md
vendored
Normal file
134
vendor/kingflamez/laravelrave/docs/verification/callback.md
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
# Callbacks
|
||||
|
||||
If the `redirect_url` is added to your payment data, Flutterwave redirects there after every payment request
|
||||
|
||||
|
||||
|
||||
|
||||
## 1. Setup your callback route
|
||||
|
||||
```php
|
||||
// The callback url after a payment
|
||||
Route::get('/rave/callback', [FlutterwaveController::class, 'callback'])->name('callback');
|
||||
```
|
||||
|
||||
|
||||
## 2. Setup your Controller
|
||||
|
||||
> Setup your controller to handle the routes. I created the `FlutterwaveController`. Use the `Flutterwave`
|
||||
> facade.
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use KingFlamez\Rave\Facades\Rave as Flutterwave;
|
||||
|
||||
class FlutterwaveController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Obtain Flutterwave callback information
|
||||
* @return void
|
||||
*/
|
||||
public function callback()
|
||||
{
|
||||
|
||||
$transactionID = Flutterwave::getTransactionIDFromCallback();
|
||||
$data = Flutterwave::verifyTransaction($transactionID);
|
||||
|
||||
dd($data);
|
||||
// Get the transaction from your DB using the transaction reference (txref)
|
||||
// Check if you have previously given value for the transaction. If you have, redirect to your successpage else, continue
|
||||
// Confirm that the $data['data']['status'] is 'successful'
|
||||
// Confirm that the currency on your db transaction is equal to the returned currency
|
||||
// Confirm that the db transaction amount is equal to the returned amount
|
||||
// Update the db transaction record (including parameters that didn't exist before the transaction is completed. for audit purpose)
|
||||
// Give value for the transaction
|
||||
// Update the transaction to note that you have given value for the transaction
|
||||
// You can also redirect to your success page from here
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## 3. Make sure to add `'redirect_url' => route('callback'),` to all your payment requests that will use the callback
|
||||
|
||||
eg
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use KingFlamez\Rave\Facades\Rave as Flutterwave;
|
||||
|
||||
class FlutterwaveController extends Controller
|
||||
{
|
||||
/**
|
||||
* Initialize Rave payment process
|
||||
* @return void
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
//This generates a payment reference
|
||||
$reference = Flutterwave::generateReference();
|
||||
|
||||
// Enter the details of the payment
|
||||
$data = [
|
||||
'payment_options' => 'card,banktransfer',
|
||||
'amount' => 500,
|
||||
'email' => request()->email,
|
||||
'tx_ref' => $reference,
|
||||
'currency' => "NGN",
|
||||
'redirect_url' => route('callback'),
|
||||
'customer' => [
|
||||
'email' => request()->email,
|
||||
"phonenumber" => request()->phone,
|
||||
"name" => request()->name
|
||||
],
|
||||
|
||||
"customizations" => [
|
||||
"title" => 'Movie Ticket',
|
||||
"description" => "20th October"
|
||||
]
|
||||
];
|
||||
|
||||
$payment = Flutterwave::initializePayment($data);
|
||||
|
||||
if (!$payment) {
|
||||
// notify something went wrong
|
||||
return;
|
||||
}
|
||||
|
||||
return redirect($payment['link']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain Rave callback information
|
||||
* @return void
|
||||
*/
|
||||
public function callback()
|
||||
{
|
||||
|
||||
$transactionID = Flutterwave::getTransactionIDFromCallback();
|
||||
$data = Flutterwave::verifyTransaction($transactionID);
|
||||
|
||||
dd($data);
|
||||
// Get the transaction from your DB using the transaction reference (txref)
|
||||
// Check if you have previously given value for the transaction. If you have, redirect to your successpage else, continue
|
||||
// Confirm that the $data['data']['status'] is 'successful'
|
||||
// Confirm that the currency on your db transaction is equal to the returned currency
|
||||
// Confirm that the db transaction amount is equal to the returned amount
|
||||
// Update the db transaction record (including parameters that didn't exist before the transaction is completed. for audit purpose)
|
||||
// Give value for the transaction
|
||||
// Update the transaction to note that you have given value for the transaction
|
||||
// You can also redirect to your success page from here
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
9
vendor/kingflamez/laravelrave/docs/verification/introduction.md
vendored
Normal file
9
vendor/kingflamez/laravelrave/docs/verification/introduction.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# Payment Verification
|
||||
|
||||
When a user is done with payment, Flutterwave would redirect to your redirect url if present or hit your webhook url:
|
||||
|
||||
Please make sure one of this is available as it is important to verify all transactions before giving value to it
|
||||
|
||||
## [Webhook Notification](/verification/webhook.html)
|
||||
|
||||
## [Callback Notification](/verification/callback.html)
|
||||
179
vendor/kingflamez/laravelrave/docs/verification/webhook.md
vendored
Normal file
179
vendor/kingflamez/laravelrave/docs/verification/webhook.md
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
# Webhooks
|
||||
|
||||
Click [here](https://developer.flutterwave.com/reference#webhook) to learn more about webhooks
|
||||
|
||||
For every transaction, Flutterwave will send a post request of the transaction to you, follow these steps to set it up
|
||||
|
||||
|
||||
|
||||
|
||||
## 1. Setup your webhook routes
|
||||
|
||||
```php
|
||||
Route::post('/webhook/flutterwave', [FlutterwaveController::class, 'webhook'])->name('webhook');
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 2. Add your webhook secret hash to your `.env`
|
||||
|
||||
```bash
|
||||
FLW_PUBLIC_KEY=FLWPUBK-xxxxxxxxxxxxxxxxxxxxx-X
|
||||
FLW_SECRET_KEY=FLWSECK-xxxxxxxxxxxxxxxxxxxxx-X
|
||||
FLW_SECRET_HASH='MY_POTTY_PATTY'
|
||||
```
|
||||
|
||||
## 3. Setup the webhook in your Flutterwave Dashboard
|
||||
|
||||
<img src="https://files.readme.io/6fc5add-Screenshot_2018-01-19_11.45.24.png" style="margin: 0 auto;" >
|
||||
|
||||
<p style="text-align: center">Login to you Flutterwave dashboard then click on settings , on the setting page navigate to webhooks to add a webhook.</p>
|
||||
|
||||
<img src="https://files.readme.io/fd1589b-webhook.png" style="margin: 0 auto;" >
|
||||
|
||||
<p style="text-align: center">Once on the webhook page, click the input text to add your webhook url and your secret hash and use the save action button to save it.</p>
|
||||
|
||||
## 4. Grant CSRF Access to Flutterwave Webhook
|
||||
|
||||
Go to `app/Http/Middleware/VerifyCsrfToken.php` and add your webhook url to the `$except` array
|
||||
|
||||
```php
|
||||
protected $except = [
|
||||
'/webhook/flutterwave',
|
||||
];
|
||||
```
|
||||
|
||||
### 4. Setup your Controller
|
||||
|
||||
> Setup your controller to handle the routes. I created the `FlutterwaveController`. Use the `Flutterwave`
|
||||
> facade.
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use KingFlamez\Rave\Facades\Rave as Flutterwave;
|
||||
|
||||
class FlutterwaveController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Receives Flutterwave webhook
|
||||
* @return void
|
||||
*/
|
||||
public function webhook(Request $request)
|
||||
{
|
||||
//This verifies the webhook is sent from Flutterwave
|
||||
$verified = Flutterwave::verifyWebhook();
|
||||
|
||||
// if it is a charge event, verify and confirm it is a successful transaction
|
||||
if ($verified && $request->event == 'charge.completed' && $request->data->status == 'successful') {
|
||||
$verificationData = Flutterwave::verifyPayment($request->data['id']);
|
||||
if ($verificationData['status'] === 'success') {
|
||||
// process for successful charge
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if it is a transfer event, verify and confirm it is a successful transfer
|
||||
if ($verified && $request->event == 'transfer.completed') {
|
||||
|
||||
$transfer = Flutterwave::transfers()->fetch($request->data['id']);
|
||||
|
||||
if($transfer['data']['status'] === 'SUCCESSFUL') {
|
||||
// update transfer status to successful in your db
|
||||
} else if ($transfer['data']['status'] === 'FAILED') {
|
||||
// update transfer status to failed in your db
|
||||
// revert customer balance back
|
||||
} else if ($transfer['data']['status'] === 'PENDING') {
|
||||
// update transfer status to pending in your db
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Webhook Samples
|
||||
|
||||
### Successful Payment
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "charge.completed",
|
||||
"data": {
|
||||
"id": 285959875,
|
||||
"tx_ref": "Links-616626414629",
|
||||
"flw_ref": "PeterEkene/FLW270177170",
|
||||
"device_fingerprint": "a42937f4a73ce8bb8b8df14e63a2df31",
|
||||
"amount": 100,
|
||||
"currency": "NGN",
|
||||
"charged_amount": 100,
|
||||
"app_fee": 1.4,
|
||||
"merchant_fee": 0,
|
||||
"processor_response": "Approved by Financial Institution",
|
||||
"auth_model": "PIN",
|
||||
"ip": "197.210.64.96",
|
||||
"narration": "CARD Transaction ",
|
||||
"status": "successful",
|
||||
"payment_type": "card",
|
||||
"created_at": "2020-07-06T19:17:04.000Z",
|
||||
"account_id": 17321,
|
||||
"customer": {
|
||||
"id": 215604089,
|
||||
"name": "Yemi Desola",
|
||||
"phone_number": null,
|
||||
"email": "user@gmail.com",
|
||||
"created_at": "2020-07-06T19:17:04.000Z"
|
||||
},
|
||||
"card": {
|
||||
"first_6digits": "123456",
|
||||
"last_4digits": "7889",
|
||||
"issuer": "VERVE FIRST CITY MONUMENT BANK PLC",
|
||||
"country": "NG",
|
||||
"type": "VERVE",
|
||||
"expiry": "02/23"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Successful Transfers
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "transfer.completed",
|
||||
"event.type": "Transfer",
|
||||
"data": {
|
||||
"id": 33286,
|
||||
"account_number": "0690000033",
|
||||
"bank_name": "ACCESS BANK NIGERIA",
|
||||
"bank_code": "044",
|
||||
"fullname": "Bale Gary",
|
||||
"created_at": "2020-04-14T16:39:17.000Z",
|
||||
"currency": "NGN",
|
||||
"debit_currency": "NGN",
|
||||
"amount": 30020,
|
||||
"fee": 26.875,
|
||||
"status": "SUCCESSFUL",
|
||||
"reference": "a0a827b1eca65311_PMCKDU_5",
|
||||
"meta": null,
|
||||
"narration": "lolololo",
|
||||
"approver": null,
|
||||
"complete_message": "Successful",
|
||||
"requires_approval": 0,
|
||||
"is_approved": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
If your webhook script performs complex logic, or makes network calls, it's possible that the script would time out before Flutterwave sees its complete execution. For that reason, you might want to have your webhook endpoint immediately acknowledge receipt by returning a 2xx HTTP status code, and then perform the rest of its duties.
|
||||
|
||||
Webhook endpoints might occasionally receive the same event more than once. We advise you to guard against duplicated event receipts by making your event processing [idempotent](https://en.wikipedia.org/wiki/Idempotence). One way I do this is making the reference unique, so once it has hit the server more than once, it won't record for subsequent events
|
||||
Reference in New Issue
Block a user