You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. namespace MirfalahTech\Laravel\Payment\Gateway\RazerPay;
  3. use Illuminate\Contracts\Config\Repository;
  4. use Illuminate\Contracts\Events\Dispatcher;
  5. use Illuminate\Http\Request;
  6. use Illuminate\Support\Arr;
  7. use Illuminate\Support\Facades\Response as Res;
  8. use MirfalahTech\Laravel\Payment\Contracts\PayableEntity;
  9. use MirfalahTech\Laravel\Payment\Contracts\PaymentGatewayDriver;
  10. use MirfalahTech\Laravel\Payment\Events\CallbackVerifiedEvent;
  11. use MirfalahTech\Laravel\Payment\Events\PaymentFailedEvent;
  12. use MirfalahTech\Laravel\Payment\Events\PaymentPendingEvent;
  13. use MirfalahTech\Laravel\Payment\Events\PaymentSuccessEvent;
  14. use MirfalahTech\Laravel\Payment\Events\ReturnVerifiedEvent;
  15. use MirfalahTech\Laravel\Payment\Facade\Payment;
  16. use MirfalahTech\Laravel\Payment\Traits\BillStatusBoolean;
  17. use Symfony\Component\HttpFoundation\Response;
  18. class RazerPayDriver implements PaymentGatewayDriver
  19. {
  20. use BillStatusBoolean;
  21. /**
  22. * @var string
  23. */
  24. protected $endpoint;
  25. /**
  26. * @var string
  27. */
  28. protected $merchant_id;
  29. /**
  30. * @var string
  31. */
  32. protected $secret_key;
  33. /**
  34. * @var string
  35. */
  36. protected $verify_key;
  37. /**
  38. * @var Repository
  39. */
  40. protected $config;
  41. /**
  42. * @var Dispatcher
  43. */
  44. protected $events;
  45. public function __construct(Repository $config, Dispatcher $events)
  46. {
  47. $this->config = $config;
  48. $this->events = $events;
  49. $this->endpoint = rtrim($config->get('payment.gateway.razerpay.endpoint'), '/');
  50. $this->merchant_id = $config->get('payment.gateway.razerpay.merchant_id');
  51. $this->secret_key = $config->get('payment.gateway.razerpay.secret_key');
  52. $this->verify_key = $config->get('payment.gateway.razerpay.verify_key');
  53. }
  54. public function createPaymentURL(PayableEntity $payable, array $options = []): string
  55. {
  56. $orderid = urlencode($payable->getBillId());
  57. $bill_name = urlencode($payable->getBillName());
  58. $bill_email = $payable->getBillEmail();
  59. $bill_mobile = $payable->getBillPhoneNumber();
  60. $detail = urlencode($payable->getBillDescription());
  61. $country = $payable->getBillCountry();
  62. $bill_desc = urlencode(preg_replace('/[^A-Z0-9,\-_]/i', '_', $detail));
  63. $amount = sprintf('%0.2f', $payable->getBillAmount());
  64. $currency = $payable->getBillCurrency();
  65. $vcode = md5($amount . $this->merchant_id . $payable->getBillId() . $this->verify_key);
  66. $query = array_merge(
  67. compact(
  68. 'amount', 'orderid', 'bill_name', 'bill_email', 'bill_mobile',
  69. 'bill_desc', 'country', 'vcode', 'currency'
  70. ),
  71. Arr::only($this->config->get('payment.gateway.razerpay.options', []), ['channel', 'returnurl', 'callbackurl']),
  72. Arr::only($options, ['channel', 'returnurl', 'callbackurl'])
  73. );
  74. return "$this->endpoint/MOLPay/pay/$this->merchant_id/?" .
  75. http_build_query($query);
  76. }
  77. public function verifyGatewayReturn(Request $request): bool
  78. {
  79. if ($this->verifyRequest($request)) {
  80. $this->events->dispatch(new ReturnVerifiedEvent('razerpay', $this, $request));
  81. $this->dispatchStatusEvent($request);
  82. return true;
  83. }
  84. return false;
  85. }
  86. public function verifyGatewayCallback(Request $request, Response &$response = null): bool
  87. {
  88. $response = $request->request->has('nbcb') ?
  89. Res::make('CBTOKEN:MPSTATOK') :
  90. Res::make('OK');
  91. if ($this->verifyRequest($request)) {
  92. $this->events->dispatch(new CallbackVerifiedEvent('razerpay', $this, $request));
  93. $this->dispatchStatusEvent($request);
  94. return true;
  95. }
  96. return false;
  97. }
  98. protected function verifyRequest(Request $request): bool
  99. {
  100. $tranID = $request->request->get('tranID');
  101. $order_id = $request->request->get('orderid');
  102. $status = $request->request->get('status');
  103. $domain = $request->request->get('domain');
  104. $amount = $request->request->get('amount');
  105. $currency = $request->request->get('currency');
  106. $appcode = $request->request->get('appcode');
  107. $pay_date = $request->request->get('paydate');
  108. $key0 = md5($tranID . $order_id . $status . $domain . $amount . $currency);
  109. $key1 = md5($pay_date . $domain . $key0 . $appcode . $this->secret_key);
  110. return $key1 == $request->request->get('skey');
  111. }
  112. protected function dispatchStatusEvent(Request $request)
  113. {
  114. switch ($this->getBillStatus($request)) {
  115. case Payment::SUCCESS:
  116. $this->events->dispatch(new PaymentSuccessEvent('razerpay', $this, $request));
  117. break;
  118. case Payment::PENDING:
  119. $this->events->dispatch(new PaymentPendingEvent('razerpay', $this, $request));
  120. break;
  121. case Payment::FAILED:
  122. $this->events->dispatch(new PaymentFailedEvent('razerpay', $this, $request));
  123. break;
  124. }
  125. }
  126. public function getBillIdFromRequest(Request $request): ?string
  127. {
  128. return $request->request->get('orderid');
  129. }
  130. public function getBillStatus(Request $request): ?int
  131. {
  132. if ($request->request->has('status')) {
  133. $status = $request->request->get('status');
  134. switch ($status){
  135. case '00':
  136. return Payment::SUCCESS;
  137. case '11':
  138. return Payment::FAILED;
  139. default:
  140. return Payment::PENDING;
  141. }
  142. } else {
  143. return null;
  144. }
  145. }
  146. }