From f7b6d8b94ada29023e75cadb37d918e2f4951f86 Mon Sep 17 00:00:00 2001 From: Saifallak Date: Mon, 8 Jul 2024 18:19:43 +0300 Subject: [PATCH 1/6] Paymob Flash New Integration --- config/nafezly-payments.php | 2 ++ src/Classes/PaymobPayment.php | 62 ++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/config/nafezly-payments.php b/config/nafezly-payments.php index b583b55..3e99b19 100644 --- a/config/nafezly-payments.php +++ b/config/nafezly-payments.php @@ -2,6 +2,8 @@ return [ #PAYMOB 'PAYMOB_API_KEY' => env('PAYMOB_API_KEY'), + 'PAYMOB_PUBLIC_API_KEY' => env('PAYMOB_PUBLIC_API_KEY'), + 'PAYMOB_SECRET_API_KEY' => env('PAYMOB_SECRET_API_KEY'), 'PAYMOB_INTEGRATION_ID' => env('PAYMOB_INTEGRATION_ID'), 'PAYMOB_IFRAME_ID' => env('PAYMOB_IFRAME_ID'), 'PAYMOB_HMAC' => env('PAYMOB_HMAC'), diff --git a/src/Classes/PaymobPayment.php b/src/Classes/PaymobPayment.php index c2d7a3e..f3ffafe 100644 --- a/src/Classes/PaymobPayment.php +++ b/src/Classes/PaymobPayment.php @@ -2,22 +2,25 @@ namespace Nafezly\Payments\Classes; +use Illuminate\Http\Client\ConnectionException; +use Illuminate\Http\Client\RequestException; use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; use Nafezly\Payments\Exceptions\MissingPaymentInfoException; use Nafezly\Payments\Interfaces\PaymentInterface; -use Nafezly\Payments\Classes\BaseController; class PaymobPayment extends BaseController implements PaymentInterface { - private $paymob_api_key; + private $paymob_public_key; + private $paymob_secret_key; private $paymob_integration_id; private $paymob_iframe_id; public function __construct() { - $this->paymob_api_key = config('nafezly-payments.PAYMOB_API_KEY'); + $this->paymob_public_key = config('nafezly-payments.PAYMOB_PUBLIC_API_KEY'); + $this->paymob_secret_key = config('nafezly-payments.PAYMOB_SECRET_API_KEY'); $this->paymob_integration_id = config('nafezly-payments.PAYMOB_INTEGRATION_ID'); $this->paymob_iframe_id = config("nafezly-payments.PAYMOB_IFRAME_ID"); $this->currency = config("nafezly-payments.PAYMOB_CURRENCY"); @@ -31,34 +34,33 @@ public function __construct() * @param null $user_email * @param null $user_phone * @param null $source - * @return void - * @throws MissingPaymentInfoException + * @return array + * @throws MissingPaymentInfoException|ConnectionException|RequestException */ public function pay($amount = null, $user_id = null, $user_first_name = null, $user_last_name = null, $user_email = null, $user_phone = null, $source = null) { - $this->setPassedVariablesToGlobal($amount,$user_id,$user_first_name,$user_last_name,$user_email,$user_phone,$source); + $this->setPassedVariablesToGlobal($amount, $user_id, $user_first_name, $user_last_name, $user_email, $user_phone, $source); $required_fields = ['amount', 'user_first_name', 'user_last_name', 'user_email', 'user_phone']; $this->checkRequiredFields($required_fields, 'PayMob'); - $request_new_token = Http::withHeaders(['content-type' => 'application/json']) - ->post('https://accept.paymobsolutions.com/api/auth/tokens', [ - "api_key" => $this->paymob_api_key - ])->json(); - - $get_order = Http::withHeaders(['content-type' => 'application/json']) - ->post('https://accept.paymobsolutions.com/api/ecommerce/orders', [ - "auth_token" => $request_new_token['token'], - "delivery_needed" => "false", - "amount_cents" => $this->amount * 100, - "items" => [] - ])->json(); - - $get_url_token = Http::withHeaders(['content-type' => 'application/json']) - ->post('https://accept.paymobsolutions.com/api/acceptance/payment_keys', [ - "auth_token" => $request_new_token['token'], - "expiration" => 36000, - "amount_cents" => $get_order['amount_cents'], - "order_id" => $get_order['id'], + $response = Http::withHeaders([ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'Authorization' => 'Token ' . $this->paymob_secret_key, + ]) + ->post('https://accept.paymob.com/v1/intention/', [ + "amount" => $this->amount * 100, + "currency" => $this->currency, + "payment_methods" => [ + (int)$this->paymob_integration_id, + // here we can add mobile wallet too if needed according to docs. + ], + "items" => [], + "customer" => [ + "first_name" => $this->user_first_name, + "last_name" => $this->user_last_name, + "email" => $this->user_email, + ], "billing_data" => [ "apartment" => "NA", "email" => $this->user_email, @@ -74,14 +76,14 @@ public function pay($amount = null, $user_id = null, $user_first_name = null, $u "last_name" => $this->user_last_name, "state" => "NA" ], - "currency" => $this->currency, - "integration_id" => $this->paymob_integration_id - ])->json(); + ]) + ->throw() + ->json(); return [ - 'payment_id'=>$get_order['id'], + 'payment_id' => $response['id'], 'html' => "", - 'redirect_url'=>"https://accept.paymobsolutions.com/api/acceptance/iframes/" . $this->paymob_iframe_id . "?payment_token=" . $get_url_token['token'] + 'redirect_url' => "https://accept.paymob.com/unifiedcheckout/?publicKey=$this->paymob_public_key&clientSecret={$response['client_secret']}" ]; } From 00dcb0eb231b21bb3ac4caf732173739c6b1f506 Mon Sep 17 00:00:00 2001 From: Saifallak Date: Mon, 8 Jul 2024 19:15:52 +0300 Subject: [PATCH 2/6] $merchant_order_id and mobile wallet uses. --- src/Classes/PaymobPayment.php | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Classes/PaymobPayment.php b/src/Classes/PaymobPayment.php index f3ffafe..f4d4745 100644 --- a/src/Classes/PaymobPayment.php +++ b/src/Classes/PaymobPayment.php @@ -14,7 +14,7 @@ class PaymobPayment extends BaseController implements PaymentInterface private $paymob_public_key; private $paymob_secret_key; private $paymob_integration_id; - private $paymob_iframe_id; + private $paymob_wallet_integration_id; public function __construct() @@ -22,7 +22,7 @@ public function __construct() $this->paymob_public_key = config('nafezly-payments.PAYMOB_PUBLIC_API_KEY'); $this->paymob_secret_key = config('nafezly-payments.PAYMOB_SECRET_API_KEY'); $this->paymob_integration_id = config('nafezly-payments.PAYMOB_INTEGRATION_ID'); - $this->paymob_iframe_id = config("nafezly-payments.PAYMOB_IFRAME_ID"); + $this->paymob_wallet_integration_id = config("nafezly-payments.PAYMOB_WALLET_INTEGRATION_ID"); $this->currency = config("nafezly-payments.PAYMOB_CURRENCY"); } @@ -35,7 +35,7 @@ public function __construct() * @param null $user_phone * @param null $source * @return array - * @throws MissingPaymentInfoException|ConnectionException|RequestException + * @throws MissingPaymentInfoException|ConnectionException|RequestException|\Random\RandomException */ public function pay($amount = null, $user_id = null, $user_first_name = null, $user_last_name = null, $user_email = null, $user_phone = null, $source = null) { @@ -43,18 +43,28 @@ public function pay($amount = null, $user_id = null, $user_first_name = null, $u $required_fields = ['amount', 'user_first_name', 'user_last_name', 'user_email', 'user_phone']; $this->checkRequiredFields($required_fields, 'PayMob'); + // New integration (Flash) that we are forced to use now + $merchant_order_id = str($this->paymob_public_key) + ->beforeLast('_') + ->append('-') + ->append(now()->getTimestampMs()) + ->append('-') + ->append(bin2hex(random_bytes(16))) + ->toString(); + $response = Http::withHeaders([ - 'Content-Type' => 'application/json', - 'Accept' => 'application/json', - 'Authorization' => 'Token ' . $this->paymob_secret_key, - ]) + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'Authorization' => 'Token ' . $this->paymob_secret_key, + ]) ->post('https://accept.paymob.com/v1/intention/', [ "amount" => $this->amount * 100, "currency" => $this->currency, "payment_methods" => [ (int)$this->paymob_integration_id, - // here we can add mobile wallet too if needed according to docs. + (int)$this->paymob_wallet_integration_id, ], + "special_reference" => $merchant_order_id, "items" => [], "customer" => [ "first_name" => $this->user_first_name, @@ -99,14 +109,14 @@ public function verify(Request $request): array if ($request['success'] == "true") { return [ 'success' => true, - 'payment_id'=>$request['order'], + 'payment_id'=>$request['merchant_order_id'] ?? $request['order'], 'message' => __('nafezly::messages.PAYMENT_DONE'), 'process_data' => $request->all() ]; } else { return [ 'success' => false, - 'payment_id'=>$request['order'], + 'payment_id'=>$request['merchant_order_id'] ?? $request['order'], 'message' => __('nafezly::messages.PAYMENT_FAILED_WITH_CODE',['CODE'=>$this->getErrorMessage($request['txn_response_code'])]), 'process_data' => $request->all() ]; @@ -115,7 +125,7 @@ public function verify(Request $request): array } else { return [ 'success' => false, - 'payment_id'=>$request['order'], + 'payment_id'=>$request['merchant_order_id'] ?? $request['order'], 'message' => __('nafezly::messages.PAYMENT_FAILED'), 'process_data' => $request->all() ]; From 150bdb6405a5bbcf542a6d7797b5a131bcda830f Mon Sep 17 00:00:00 2001 From: Saifallak Date: Mon, 8 Jul 2024 19:19:19 +0300 Subject: [PATCH 3/6] comments and fix typo. --- src/Classes/PaymobPayment.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Classes/PaymobPayment.php b/src/Classes/PaymobPayment.php index f4d4745..9c1ea57 100644 --- a/src/Classes/PaymobPayment.php +++ b/src/Classes/PaymobPayment.php @@ -43,7 +43,8 @@ public function pay($amount = null, $user_id = null, $user_first_name = null, $u $required_fields = ['amount', 'user_first_name', 'user_last_name', 'user_email', 'user_phone']; $this->checkRequiredFields($required_fields, 'PayMob'); - // New integration (Flash) that we are forced to use now + // New integration (Flash) that we are forced to use now doesnt let us register order first, so we generate one for us. + // Docs: https://developers.paymob.com/egypt/checkout-api/integration-guide-and-api-reference/create-intention-payment-api $merchant_order_id = str($this->paymob_public_key) ->beforeLast('_') ->append('-') @@ -91,7 +92,7 @@ public function pay($amount = null, $user_id = null, $user_first_name = null, $u ->json(); return [ - 'payment_id' => $response['id'], + 'payment_id' => $merchant_order_id, 'html' => "", 'redirect_url' => "https://accept.paymob.com/unifiedcheckout/?publicKey=$this->paymob_public_key&clientSecret={$response['client_secret']}" ]; From cea1a10459e61ac4df1398b1399432f62872cf27 Mon Sep 17 00:00:00 2001 From: Saifallak Date: Mon, 8 Jul 2024 19:30:46 +0300 Subject: [PATCH 4/6] Apply New Wallet Integration. --- src/Classes/PaymobPayment.php | 5 +- src/Classes/PaymobWalletPayment.php | 84 +++++++++++++++-------------- 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/Classes/PaymobPayment.php b/src/Classes/PaymobPayment.php index 9c1ea57..99a365f 100644 --- a/src/Classes/PaymobPayment.php +++ b/src/Classes/PaymobPayment.php @@ -14,7 +14,6 @@ class PaymobPayment extends BaseController implements PaymentInterface private $paymob_public_key; private $paymob_secret_key; private $paymob_integration_id; - private $paymob_wallet_integration_id; public function __construct() @@ -22,7 +21,6 @@ public function __construct() $this->paymob_public_key = config('nafezly-payments.PAYMOB_PUBLIC_API_KEY'); $this->paymob_secret_key = config('nafezly-payments.PAYMOB_SECRET_API_KEY'); $this->paymob_integration_id = config('nafezly-payments.PAYMOB_INTEGRATION_ID'); - $this->paymob_wallet_integration_id = config("nafezly-payments.PAYMOB_WALLET_INTEGRATION_ID"); $this->currency = config("nafezly-payments.PAYMOB_CURRENCY"); } @@ -39,7 +37,7 @@ public function __construct() */ public function pay($amount = null, $user_id = null, $user_first_name = null, $user_last_name = null, $user_email = null, $user_phone = null, $source = null) { - $this->setPassedVariablesToGlobal($amount, $user_id, $user_first_name, $user_last_name, $user_email, $user_phone, $source); + $this->setPassedVariablesToGlobal($amount,$user_id,$user_first_name,$user_last_name,$user_email,$user_phone,$source); $required_fields = ['amount', 'user_first_name', 'user_last_name', 'user_email', 'user_phone']; $this->checkRequiredFields($required_fields, 'PayMob'); @@ -63,7 +61,6 @@ public function pay($amount = null, $user_id = null, $user_first_name = null, $u "currency" => $this->currency, "payment_methods" => [ (int)$this->paymob_integration_id, - (int)$this->paymob_wallet_integration_id, ], "special_reference" => $merchant_order_id, "items" => [], diff --git a/src/Classes/PaymobWalletPayment.php b/src/Classes/PaymobWalletPayment.php index c631c44..8a6d800 100644 --- a/src/Classes/PaymobWalletPayment.php +++ b/src/Classes/PaymobWalletPayment.php @@ -2,22 +2,25 @@ namespace Nafezly\Payments\Classes; +use Illuminate\Http\Client\ConnectionException; +use Illuminate\Http\Client\RequestException; use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; use Nafezly\Payments\Exceptions\MissingPaymentInfoException; use Nafezly\Payments\Interfaces\PaymentInterface; -use Nafezly\Payments\Classes\BaseController; class PaymobWalletPayment extends BaseController implements PaymentInterface { - private $paymob_api_key; + private $paymob_public_key; + private $paymob_secret_key; private $paymob_wallet_integration_id; public function __construct() { - $this->paymob_api_key = config('nafezly-payments.PAYMOB_API_KEY'); - $this->currency = config("nafezly-payments.PAYMOB_CURRENCY"); + $this->paymob_public_key = config('nafezly-payments.PAYMOB_PUBLIC_API_KEY'); + $this->paymob_secret_key = config('nafezly-payments.PAYMOB_SECRET_API_KEY'); $this->paymob_wallet_integration_id = config("nafezly-payments.PAYMOB_WALLET_INTEGRATION_ID"); + $this->currency = config("nafezly-payments.PAYMOB_CURRENCY"); } /** @@ -28,8 +31,8 @@ public function __construct() * @param null $user_email * @param null $user_phone * @param null $source - * @return void - * @throws MissingPaymentInfoException + * @return array + * @throws MissingPaymentInfoException|ConnectionException|RequestException|\Random\RandomException */ public function pay($amount = null, $user_id = null, $user_first_name = null, $user_last_name = null, $user_email = null, $user_phone = null, $source = null) { @@ -37,24 +40,34 @@ public function pay($amount = null, $user_id = null, $user_first_name = null, $u $required_fields = ['amount', 'user_first_name', 'user_last_name', 'user_email', 'user_phone']; $this->checkRequiredFields($required_fields, 'PayMob'); - $request_new_token = Http::withHeaders(['content-type' => 'application/json']) - ->post('https://accept.paymobsolutions.com/api/auth/tokens', [ - "api_key" => $this->paymob_api_key - ])->json(); + // New integration (Flash) that we are forced to use now doesnt let us register order first, so we generate one for us. + // Docs: https://developers.paymob.com/egypt/checkout-api/integration-guide-and-api-reference/create-intention-payment-api + $merchant_order_id = str($this->paymob_public_key) + ->beforeLast('_') + ->append('-') + ->append(now()->getTimestampMs()) + ->append('-') + ->append(bin2hex(random_bytes(16))) + ->toString(); - $get_order = Http::withHeaders(['content-type' => 'application/json']) - ->post('https://accept.paymobsolutions.com/api/ecommerce/orders', [ - "auth_token" => $request_new_token['token'], - "delivery_needed" => "false", - "amount_cents" => $this->amount * 100, - "items" => [] - ])->json(); - $get_url_token = Http::withHeaders(['content-type' => 'application/json']) - ->post('https://accept.paymobsolutions.com/api/acceptance/payment_keys', [ - "auth_token" => $request_new_token['token'], - "expiration" => 36000, - "amount_cents" => $get_order['amount_cents'], - "order_id" => $get_order['id'], + $response = Http::withHeaders([ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'Authorization' => 'Token ' . $this->paymob_secret_key, + ]) + ->post('https://accept.paymob.com/v1/intention/', [ + "amount" => $this->amount * 100, + "currency" => $this->currency, + "payment_methods" => [ + (int)$this->paymob_wallet_integration_id, + ], + "special_reference" => $merchant_order_id, + "items" => [], + "customer" => [ + "first_name" => $this->user_first_name, + "last_name" => $this->user_last_name, + "email" => $this->user_email, + ], "billing_data" => [ "apartment" => "NA", "email" => $this->user_email, @@ -70,23 +83,14 @@ public function pay($amount = null, $user_id = null, $user_first_name = null, $u "last_name" => $this->user_last_name, "state" => "NA" ], - "currency" => $this->currency, - "integration_id" => $this->paymob_wallet_integration_id, - 'lock_order_when_paid'=>true - ])->json(); + ]) + ->throw() + ->json(); - $get_pay_link = Http::withHeaders(['content-type' => 'application/json']) - ->post('https://accept.paymob.com/api/acceptance/payments/pay', [ - 'source'=>[ - "identifier"=>$this->user_phone, - 'subtype'=>"WALLET" - ], - "payment_token"=>$get_url_token['token'] - ])->json(); return [ - 'payment_id'=>$get_order['id'], + 'payment_id' => $merchant_order_id, 'html' => "", - 'redirect_url'=>$get_pay_link['redirect_url'] + 'redirect_url' => "https://accept.paymob.com/unifiedcheckout/?publicKey=$this->paymob_public_key&clientSecret={$response['client_secret']}" ]; } @@ -103,14 +107,14 @@ public function verify(Request $request): array if ($request['success'] == "true") { return [ 'success' => true, - 'payment_id'=>$request['order'], + 'payment_id'=>$request['merchant_order_id'] ?? $request['order'], 'message' => __('nafezly::messages.PAYMENT_DONE'), 'process_data' => $request->all() ]; } else { return [ 'success' => false, - 'payment_id'=>$request['order'], + 'payment_id'=>$request['merchant_order_id'] ?? $request['order'], 'message' => __('nafezly::messages.PAYMENT_FAILED_WITH_CODE',['CODE'=>$this->getErrorMessage($request['txn_response_code'])]), 'process_data' => $request->all() ]; @@ -119,7 +123,7 @@ public function verify(Request $request): array } else { return [ 'success' => false, - 'payment_id'=>$request['order'], + 'payment_id'=>$request['merchant_order_id'] ?? $request['order'], 'message' => __('nafezly::messages.PAYMENT_FAILED'), 'process_data' => $request->all() ]; From 550ba01d59942c4b49f097a20b76d024e6511d1d Mon Sep 17 00:00:00 2001 From: Saifallak Date: Mon, 8 Jul 2024 21:59:19 +0300 Subject: [PATCH 5/6] UnifiedPaymobPayment --- config/nafezly-payments.php | 3 + src/Classes/UnifiedPaymobPayment.php | 180 +++++++++++++++++++++++++ src/NafezlyPaymentsServiceProvider.php | 4 + 3 files changed, 187 insertions(+) create mode 100644 src/Classes/UnifiedPaymobPayment.php diff --git a/config/nafezly-payments.php b/config/nafezly-payments.php index 3e99b19..39bf370 100644 --- a/config/nafezly-payments.php +++ b/config/nafezly-payments.php @@ -9,6 +9,9 @@ 'PAYMOB_HMAC' => env('PAYMOB_HMAC'), 'PAYMOB_CURRENCY'=> env('PAYMOB_CURRENCY',"EGP"), + #PAYMOB UNIFIED CHECKOUT, aka: Flash Checkout, ex: 5000,5001, default wii take PAYMOB_INTEGRATION_ID and PAYMOB_WALLET_INTEGRATION_ID as values, + 'PAYMOB_UNIFIED_INTEGRATION_IDS' => env('PAYMOB_UNIFIED_INTEGRATION_IDS'), + #HYPERPAY 'HYPERPAY_BASE_URL' => env('HYPERPAY_BASE_URL', "https://eu-test.oppwa.com"), 'HYPERPAY_URL' => env('HYPERPAY_URL', env('HYPERPAY_BASE_URL') . "/v1/checkouts"), diff --git a/src/Classes/UnifiedPaymobPayment.php b/src/Classes/UnifiedPaymobPayment.php new file mode 100644 index 0000000..eadffb2 --- /dev/null +++ b/src/Classes/UnifiedPaymobPayment.php @@ -0,0 +1,180 @@ +paymob_public_key = config('nafezly-payments.PAYMOB_PUBLIC_API_KEY'); + $this->paymob_secret_key = config('nafezly-payments.PAYMOB_SECRET_API_KEY'); + $this->paymob_integration_ids = explode(',', config('nafezly-payments.PAYMOB_UNIFIED_INTEGRATION_IDS', '')); + if (!filled($this->paymob_integration_ids)) { + $this->paymob_integration_ids = [ + config("nafezly-payments.PAYMOB_INTEGRATION_ID", ''), + config("nafezly-payments.PAYMOB_WALLET_INTEGRATION_ID", ''), + ]; + } + $this->currency = config("nafezly-payments.PAYMOB_CURRENCY"); + } + + /** + * @param $amount + * @param null $user_id + * @param null $user_first_name + * @param null $user_last_name + * @param null $user_email + * @param null $user_phone + * @param null $source + * @return array + * @throws MissingPaymentInfoException|ConnectionException|RequestException|\Random\RandomException + */ + public function pay($amount = null, $user_id = null, $user_first_name = null, $user_last_name = null, $user_email = null, $user_phone = null, $source = null) + { + $this->setPassedVariablesToGlobal($amount, $user_id, $user_first_name, $user_last_name, $user_email, $user_phone, $source); + $required_fields = ['amount', 'user_first_name', 'user_last_name', 'user_email', 'user_phone']; + $this->checkRequiredFields($required_fields, 'PayMob'); + + // New integration (Flash) that we are forced to use now doesnt let us register order first, so we generate one for us. + // Docs: https://developers.paymob.com/egypt/checkout-api/integration-guide-and-api-reference/create-intention-payment-api + $merchant_order_id = str($this->paymob_public_key) + ->beforeLast('_') + ->append('-') + ->append(now()->getTimestampMs()) + ->append('-') + ->append(bin2hex(random_bytes(16))) + ->toString(); + + $response = Http::withHeaders([ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'Authorization' => 'Token ' . $this->paymob_secret_key, + ]) + ->post('https://accept.paymob.com/v1/intention/', [ + "amount" => $this->amount * 100, + "currency" => $this->currency, + "payment_methods" => collect($this->paymob_integration_ids) + // clear null values if exists. + ->filter() + // convert all to int if numeric (because paymob won't accept id as string + // but you can send integration names too. + ->map(function ($id) { + return is_numeric($id) ? (int)$id : $id; + })->toArray(), + "special_reference" => $merchant_order_id, + "items" => [], + "customer" => [ + "first_name" => $this->user_first_name, + "last_name" => $this->user_last_name, + "email" => $this->user_email, + ], + "billing_data" => [ + "apartment" => "NA", + "email" => $this->user_email, + "floor" => "NA", + "first_name" => $this->user_first_name, + "street" => "NA", + "building" => "NA", + "phone_number" => $this->user_phone, + "shipping_method" => "NA", + "postal_code" => "NA", + "city" => "NA", + "country" => "NA", + "last_name" => $this->user_last_name, + "state" => "NA" + ], + ]) + ->throw() + ->json(); + + return [ + 'payment_id' => $merchant_order_id, + 'html' => "", + 'redirect_url' => "https://accept.paymob.com/unifiedcheckout/?publicKey=$this->paymob_public_key&clientSecret={$response['client_secret']}" + ]; + } + + /** + * @param Request $request + * @return array + */ + public function verify(Request $request): array + { + $string = $request['amount_cents'] . $request['created_at'] . $request['currency'] . $request['error_occured'] . $request['has_parent_transaction'] . $request['id'] . $request['integration_id'] . $request['is_3d_secure'] . $request['is_auth'] . $request['is_capture'] . $request['is_refunded'] . $request['is_standalone_payment'] . $request['is_voided'] . $request['order'] . $request['owner'] . $request['pending'] . $request['source_data_pan'] . $request['source_data_sub_type'] . $request['source_data_type'] . $request['success']; + + if (hash_equals(hash_hmac('sha512', $string, config('nafezly-payments.PAYMOB_HMAC')), $request['hmac'])) { + if ($request['success'] == "true") { + return [ + 'success' => true, + 'payment_id' => $request['merchant_order_id'] ?? $request['order'], + 'message' => __('nafezly::messages.PAYMENT_DONE'), + 'process_data' => $request->all() + ]; + } else { + return [ + 'success' => false, + 'payment_id' => $request['merchant_order_id'] ?? $request['order'], + 'message' => __('nafezly::messages.PAYMENT_FAILED_WITH_CODE', ['CODE' => $this->getErrorMessage($request['txn_response_code'])]), + 'process_data' => $request->all() + ]; + } + + } else { + return [ + 'success' => false, + 'payment_id' => $request['merchant_order_id'] ?? $request['order'], + 'message' => __('nafezly::messages.PAYMENT_FAILED'), + 'process_data' => $request->all() + ]; + } + } + + public function getErrorMessage($code) + { + $errors = [ + 'BLOCKED' => __('nafezly::messages.Process_Has_Been_Blocked_From_System'), + 'B' => __('nafezly::messages.Process_Has_Been_Blocked_From_System'), + '5' => __('nafezly::messages.Balance_is_not_enough'), + 'F' => __('nafezly::messages.Your_card_is_not_authorized_with_3D_secure'), + '7' => __('nafezly::messages.Incorrect_card_expiration_date'), + '2' => __('nafezly::messages.Declined'), + '6051' => __('nafezly::messages.Balance_is_not_enough'), + '637' => __('nafezly::messages.The_OTP_number_was_entered_incorrectly'), + '11' => __('nafezly::messages.Security_checks_are_not_passed_by_the_system'), + ]; + if (isset($errors[$code])) + return $errors[$code]; + else + return __('nafezly::messages.An_error_occurred_while_executing_the_operation'); + } + + public function refund($transaction_id, $amount): array + { + $request_new_token = Http::withHeaders(['content-type' => 'application/json']) + ->post('https://accept.paymobsolutions.com/api/auth/tokens', [ + "api_key" => $this->paymob_api_key + ])->json(); + $refund_process = Http::withHeaders(['content-type' => 'application/json']) + ->post('https://accept.paymob.com/api/acceptance/void_refund/refund', ['auth_token' => $request_new_token['token'], 'transaction_id' => $transaction_id, 'amount_cents' => $amount])->json(); + + dd($refund_process); + return [ + 'transaction_id' => $transaction_id, + 'amount' => $amount, + ]; + + } + +} \ No newline at end of file diff --git a/src/NafezlyPaymentsServiceProvider.php b/src/NafezlyPaymentsServiceProvider.php index 4a1cb56..1324740 100644 --- a/src/NafezlyPaymentsServiceProvider.php +++ b/src/NafezlyPaymentsServiceProvider.php @@ -13,6 +13,7 @@ use Nafezly\Payments\Classes\TapPayment; use Nafezly\Payments\Classes\OpayPayment; use Nafezly\Payments\Classes\PaymobWalletPayment; +use Nafezly\Payments\Classes\UnifiedPaymobPayment; class NafezlyPaymentsServiceProvider extends ServiceProvider { @@ -81,6 +82,9 @@ public function register() $this->app->bind(PaymobWalletPayment::class, function () { return new PaymobWalletPayment(); }); + $this->app->bind(UnifiedPaymobPayment::class, function () { + return new UnifiedPaymobPayment(); + }); $this->app->bind(PaytabsPayment::class, function () { return new PaytabsPayment(); }); From 2b54b0d53347a44c699c36692f159fbada1de5b2 Mon Sep 17 00:00:00 2001 From: Saifallak Date: Mon, 8 Jul 2024 22:08:49 +0300 Subject: [PATCH 6/6] fix. --- src/Classes/UnifiedPaymobPayment.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Classes/UnifiedPaymobPayment.php b/src/Classes/UnifiedPaymobPayment.php index eadffb2..4b33306 100644 --- a/src/Classes/UnifiedPaymobPayment.php +++ b/src/Classes/UnifiedPaymobPayment.php @@ -20,8 +20,9 @@ public function __construct() { $this->paymob_public_key = config('nafezly-payments.PAYMOB_PUBLIC_API_KEY'); $this->paymob_secret_key = config('nafezly-payments.PAYMOB_SECRET_API_KEY'); - $this->paymob_integration_ids = explode(',', config('nafezly-payments.PAYMOB_UNIFIED_INTEGRATION_IDS', '')); - if (!filled($this->paymob_integration_ids)) { + if (filled(config('nafezly-payments.PAYMOB_UNIFIED_INTEGRATION_IDS', ''))) { + $this->paymob_integration_ids = explode(',', config('nafezly-payments.PAYMOB_UNIFIED_INTEGRATION_IDS', '')); + } else { $this->paymob_integration_ids = [ config("nafezly-payments.PAYMOB_INTEGRATION_ID", ''), config("nafezly-payments.PAYMOB_WALLET_INTEGRATION_ID", ''),