<?php
namespace App\Traits\PaymentGateway;
use App\Constants\PaymentGatewayConst;
use App\Models\TemporaryData;
use Exception;
use Srmklive\PayPal\Services\PayPal as PayPalClient;
use Illuminate\Support\Str;
trait Paypal
{
public function paypalInit($output = null) {
if(!$output) $output = $this->output;
$credentials = $this->getPaypalCredentials($output);
$config = $this->paypalConfig($credentials,$output['amount']);
$paypalProvider = new PayPalClient;
$paypalProvider->setApiCredentials($config);
$paypalProvider->getAccessToken();
$redirection = $this->getRedirection();
$url_parameter = $this->getUrlParams();
$response = $paypalProvider->createOrder([
"intent" => "CAPTURE",
"application_context" => [
"return_url" => $this->setGatewayRoute($redirection['return_url'],PaymentGatewayConst::PAYPAL,$url_parameter),
"cancel_url" => $this->setGatewayRoute($redirection['cancel_url'],PaymentGatewayConst::PAYPAL,$url_parameter),
],
"purchase_units" => [
0 => [
"amount" => [
"currency_code" => $output['amount']->sender_cur_code ?? '',
"value" => $output['amount']->total_amount ? number_format($output['amount']->total_amount,2,'.','') : 0,
]
]
]
]);
if(isset($response['id']) && $response['id'] != "" && isset($response['status']) && $response['status'] == "CREATED" && isset($response['links']) && is_array($response['links'])) {
foreach($response['links'] as $item) {
if($item['rel'] == "approve") {
$this->paypalJunkInsert($response);
if(request()->expectsJson()) {
$this->output['redirection_response'] = $response;
$this->output['redirect_links'] = $response['links'];
$this->output['redirect_url'] = $item['href'];
return $this->get();
break;
}
return redirect()->away($item['href']);
break;
}
}
}
if(isset($response['error']) && is_array($response['error'])) {
throw new Exception($response['error']['message']);
}
throw new Exception("Something went wrong! Please try again.");
}
public function getPaypalCredentials($output) {
$gateway = $output['gateway'] ?? null;
if(!$gateway) throw new Exception("Payment gateway not available");
$client_id_sample = ['api key','api_key','client id','primary key'];
$client_secret_sample = ['client_secret','client secret','secret','secret key','secret id'];
$client_id = '';
$outer_break = false;
foreach($client_id_sample as $item) {
if($outer_break == true) {
break;
}
$modify_item = $this->paypalPlainText($item);
foreach($gateway->credentials ?? [] as $gatewayInput) {
$label = $gatewayInput->label ?? "";
$label = $this->paypalPlainText($label);
if($label == $modify_item) {
$client_id = $gatewayInput->value ?? "";
$outer_break = true;
break;
}
}
}
$secret_id = '';
$outer_break = false;
foreach($client_secret_sample as $item) {
if($outer_break == true) {
break;
}
$modify_item = $this->paypalPlainText($item);
foreach($gateway->credentials ?? [] as $gatewayInput) {
$label = $gatewayInput->label ?? "";
$label = $this->paypalPlainText($label);
if($label == $modify_item) {
$secret_id = $gatewayInput->value ?? "";
$outer_break = true;
break;
}
}
}
$mode = $gateway->env;
$paypal_register_mode = [
PaymentGatewayConst::ENV_SANDBOX => "sandbox",
PaymentGatewayConst::ENV_PRODUCTION => "live",
];
if(array_key_exists($mode,$paypal_register_mode)) {
$mode = $paypal_register_mode[$mode];
}else {
$mode = "sandbox";
}
return (object) [
'client_id' => $client_id,
'client_secret' => $secret_id,
'mode' => $mode,
];
}
public function paypalPlainText($string) {
$string = Str::lower($string);
return preg_replace("/[^A-Za-z0-9]/","",$string);
}
public static function paypalConfig($credentials, $amount_info)
{
$config = [
'mode' => $credentials->mode ?? 'sandbox',
'sandbox' => [
'client_id' => $credentials->client_id ?? "",
'client_secret' => $credentials->client_secret ?? "",
'app_id' => "APP-80W284485P519543T",
],
'live' => [
'client_id' => $credentials->client_id ?? "",
'client_secret' => $credentials->client_secret ?? "",
'app_id' => "",
],
'payment_action' => 'Sale', // Can only be 'Sale', 'Authorization' or 'Order'
'currency' => $amount_info->sender_cur_code ?? "",
'notify_url' => "", // Change this accordingly for your application.
'locale' => 'en_US', // force gateway language i.e. it_IT, es_ES, en_US ... (for express checkout only)
'validate_ssl' => true, // Validate SSL when creating api client.
];
return $config;
}
public function paypalJunkInsert($response) {
$output = $this->output;
$data = [
'gateway' => $output['gateway']->id,
'currency' => $output['currency']->id,
'amount' => json_decode(json_encode($output['amount']),true),
'response' => $response,
'wallet_table' => $output['wallet']->getTable(),
'wallet_id' => $output['wallet']->id,
'creator_table' => auth()->guard(get_auth_guard())->user()->getTable(),
'creator_id' => auth()->guard(get_auth_guard())->user()->id,
'creator_guard' => get_auth_guard(),
];
return TemporaryData::create([
'type' => PaymentGatewayConst::TYPEADDMONEY,
'identifier' => $response['id'],
'data' => $data,
]);
}
public function paypalSuccess($output = null) {
if(!$output) $output = $this->output;
$token = $this->output['tempData']['identifier'] ?? "";
$credentials = $this->getPaypalCredentials($output);
$config = $this->paypalConfig($credentials,$output['amount']);
$paypalProvider = new PayPalClient;
$paypalProvider->setApiCredentials($config);
$paypalProvider->getAccessToken();
$response = $paypalProvider->capturePaymentOrder($token);
if(isset($response['status']) && $response['status'] == 'COMPLETED') {
return $this->paypalPaymentCaptured($response,$output);
}else {
throw new Exception('Transaction failed. Payment captured failed.');
}
if(empty($token)) throw new Exception('Transaction failed. Record didn\'t saved properly. Please try again.');
}
public function paypalPaymentCaptured($response,$output) {
// payment successfully captured record saved to database
$output['capture'] = $response;
try{
$this->createTransaction($output);
}catch(Exception $e) {
throw new Exception($e->getMessage());
}
return true;
}
public static function isPaypal($gateway) {
$search_keyword = ['paypal','paypal gateway','paypal payment gateway','gateway paypal','paypal automatic gateway','paypal automatic'];
$gateway_name = $gateway->name;
$search_text = Str::lower($gateway_name);
$search_text = preg_replace("/[^A-Za-z0-9]/","",$search_text);
foreach($search_keyword as $keyword) {
$keyword = Str::lower($keyword);
$keyword = preg_replace("/[^A-Za-z0-9]/","",$keyword);
if($keyword == $search_text) {
return true;
break;
}
}
return false;
}
}
Initiates a new payment transaction.
create-order
| Parameter | Type | Details |
|---|---|---|
| amount | decimal | Your Amount , Must be rounded at 2 precision. |
| currency | string | Currency Code, Must be in Upper Case (Alpha-3 code) |
| success_url | string | Enter your return or success URL |
| cancel_url | string (optional) | Enter your cancel or failed URL |
Request Example (guzzle)
<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', $base_url.'create-order', [
'headers' => [
'Authorization' => 'Bearer '. $authorizationToken,
'accept' => 'application/json',
'content-type' => 'application/json',
],
'form_params' => [
'amount' => '$amount',
'currency' => 'currency',
'success_url' => 'success_url',
'cancel_url' => 'cancel_url',
],
]);
echo $response->getBody();
**Response: SUCCESS (200 OK)**
{
"message": {
"success": [
"Order created successfully."
]
},
"data": {
"redirect_url":"https://example.com/login/OISADFDFSDFSF",
"order_details":{
"amount" : "10",
"fixed_charge" : 2,
"percent_charge" : 1,
"total_charge" : 3,
"total_payable" : 13,
"currency" : "USD",
"expiry_time": "2024-04-25T06:48:35.984285Z",
"success_url": "http://127.0.0.1/nfcpay/user/transaction/success",
"cancel_url": "http://127.0.0.1/nfcpay/user/transaction/cancel"
}
},
"type": "success"
}
**Response: ERROR (400 FAILED)**
{
"message": {
"error": [
"Invalid token."
]
},
"data": null,
"type": "error"
}