mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-12 22:22:32 +01:00
Merge pull request #6794 from beganovich/v5-razorpay
Razorpay: All in one checkout
This commit is contained in:
commit
40a7562b52
@ -137,6 +137,11 @@ class Gateway extends StaticModel
|
||||
GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true] // GoCardless
|
||||
];
|
||||
break;
|
||||
case 58:
|
||||
return [
|
||||
GatewayType::HOSTED_PAGE => ['refund' => false, 'token_billing' => false] // Razorpay
|
||||
];
|
||||
break;
|
||||
default:
|
||||
return [];
|
||||
break;
|
||||
|
@ -28,6 +28,7 @@ class GatewayType extends StaticModel
|
||||
const KBC = 11;
|
||||
const BANCONTACT = 12;
|
||||
const IDEAL = 13;
|
||||
const HOSTED_PAGE = 14; // For gateways that contain multiple methods.
|
||||
|
||||
public function gateway()
|
||||
{
|
||||
@ -66,6 +67,8 @@ class GatewayType extends StaticModel
|
||||
return ctrans('texts.bancontact');
|
||||
case self::IDEAL:
|
||||
return ctrans('texts.ideal');
|
||||
case self::HOSTED_PAGE:
|
||||
return ctrans('texts.aio_checkout');
|
||||
default:
|
||||
return 'Undefined.';
|
||||
break;
|
||||
|
@ -46,6 +46,7 @@ class PaymentType extends StaticModel
|
||||
const KBC = 35;
|
||||
const BANCONTACT = 36;
|
||||
const IDEAL = 37;
|
||||
const HOSTED_PAGE = 38;
|
||||
|
||||
public static function parseCardType($cardName)
|
||||
{
|
||||
|
@ -74,6 +74,7 @@ class SystemLog extends Model
|
||||
const TYPE_EWAY = 313;
|
||||
const TYPE_SQUARE = 320;
|
||||
const TYPE_GOCARDLESS = 321;
|
||||
const TYPE_RAZORPAY = 322;
|
||||
|
||||
const TYPE_QUOTA_EXCEEDED = 400;
|
||||
const TYPE_UPSTREAM_FAILURE = 401;
|
||||
|
184
app/PaymentDrivers/Razorpay/Hosted.php
Normal file
184
app/PaymentDrivers/Razorpay/Hosted.php
Normal file
@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers\Razorpay;
|
||||
|
||||
use App\Exceptions\PaymentFailed;
|
||||
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
|
||||
use App\Http\Requests\Request;
|
||||
use App\Jobs\Mail\PaymentFailureMailer;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PaymentType;
|
||||
use App\Models\SystemLog;
|
||||
use App\PaymentDrivers\Common\MethodInterface;
|
||||
use App\PaymentDrivers\RazorpayPaymentDriver;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\View\View;
|
||||
use Razorpay\Api\Errors\SignatureVerificationError;
|
||||
|
||||
class Hosted implements MethodInterface
|
||||
{
|
||||
protected RazorpayPaymentDriver $razorpay;
|
||||
|
||||
public function __construct(RazorpayPaymentDriver $razorpay)
|
||||
{
|
||||
$this->razorpay = $razorpay;
|
||||
|
||||
$this->razorpay->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the authorization page for Razorpay.
|
||||
*
|
||||
* @param array $data
|
||||
* @return View
|
||||
*/
|
||||
public function authorizeView(array $data): View
|
||||
{
|
||||
return render('gateways.razorpay.hosted.authorize', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the authorization page for Razorpay.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function authorizeResponse(Request $request): RedirectResponse
|
||||
{
|
||||
return redirect()->route('client.payment_methods.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Payment view for the Razorpay.
|
||||
*
|
||||
* @param array $data
|
||||
* @return View
|
||||
*/
|
||||
public function paymentView(array $data): View
|
||||
{
|
||||
$order = $this->razorpay->gateway->order->create([
|
||||
'currency' => $this->razorpay->client->currency()->code,
|
||||
'amount' => $this->razorpay->convertToRazorpayAmount((float) $this->razorpay->payment_hash->data->amount_with_fee),
|
||||
]);
|
||||
|
||||
$this->razorpay->payment_hash->withData('order_id', $order->id);
|
||||
$this->razorpay->payment_hash->withData('order_amount', $order->amount);
|
||||
|
||||
$data['gateway'] = $this->razorpay;
|
||||
|
||||
$data['options'] = [
|
||||
'key' => $this->razorpay->company_gateway->getConfigField('apiKey'),
|
||||
'amount' => $this->razorpay->convertToRazorpayAmount((float) $this->razorpay->payment_hash->data->amount_with_fee),
|
||||
'currency' => $this->razorpay->client->currency()->code,
|
||||
'name' => $this->razorpay->company_gateway->company->present()->name(),
|
||||
'order_id' => $order->id,
|
||||
];
|
||||
|
||||
return render('gateways.razorpay.hosted.pay', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle payments page for Razorpay.
|
||||
*
|
||||
* @param PaymentResponseRequest $request
|
||||
* @return void
|
||||
*/
|
||||
public function paymentResponse(PaymentResponseRequest $request)
|
||||
{
|
||||
$request->validate([
|
||||
'payment_hash' => ['required'],
|
||||
'razorpay_payment_id' => ['required'],
|
||||
'razorpay_signature' => ['required'],
|
||||
]);
|
||||
|
||||
if (! property_exists($this->razorpay->payment_hash->data, 'order_id')) {
|
||||
throw new PaymentFailed('Missing [order_id] property. Please contact the administrator. Reference: ' . $this->razorpay->payment_hash->hash);
|
||||
}
|
||||
|
||||
try {
|
||||
$attributes = [
|
||||
'razorpay_order_id' => $this->razorpay->payment_hash->data->order_id,
|
||||
'razorpay_payment_id' => $request->razorpay_payment_id,
|
||||
'razorpay_signature' => $request->razorpay_signature,
|
||||
];
|
||||
|
||||
$this->razorpay->gateway->utility->verifyPaymentSignature($attributes);
|
||||
|
||||
return $this->processSuccessfulPayment($request->razorpay_payment_id);
|
||||
}
|
||||
catch (SignatureVerificationError $exception) {
|
||||
return $this->processUnsuccessfulPayment($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the successful payment for Razorpay.
|
||||
*
|
||||
* @param string $payment_id
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function processSuccessfulPayment(string $payment_id): RedirectResponse
|
||||
{
|
||||
$data = [
|
||||
'gateway_type_id' => GatewayType::HOSTED_PAGE,
|
||||
'amount' => array_sum(array_column($this->razorpay->payment_hash->invoices(), 'amount')) + $this->razorpay->payment_hash->fee_total,
|
||||
'payment_type' => PaymentType::HOSTED_PAGE,
|
||||
'transaction_reference' => $payment_id,
|
||||
];
|
||||
|
||||
$payment_record = $this->razorpay->createPayment($data, Payment::STATUS_COMPLETED);
|
||||
|
||||
SystemLogger::dispatch(
|
||||
['response' => $payment_id, 'data' => $data],
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||
SystemLog::TYPE_RAZORPAY,
|
||||
$this->razorpay->client,
|
||||
$this->razorpay->client->company,
|
||||
);
|
||||
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->razorpay->encodePrimaryKey($payment_record->id)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle unsuccessful payment for Razorpay.
|
||||
*
|
||||
* @param Exception $exception
|
||||
* @throws PaymentFailed
|
||||
* @return void
|
||||
*/
|
||||
public function processUnsuccessfulPayment(\Exception $exception): void
|
||||
{
|
||||
PaymentFailureMailer::dispatch(
|
||||
$this->razorpay->client,
|
||||
$exception->getMessage(),
|
||||
$this->razorpay->client->company,
|
||||
$this->razorpay->payment_hash->data->amount_with_fee
|
||||
);
|
||||
|
||||
SystemLogger::dispatch(
|
||||
$exception->getMessage(),
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||
SystemLog::TYPE_RAZORPAY,
|
||||
$this->razorpay->client,
|
||||
$this->razorpay->client->company,
|
||||
);
|
||||
|
||||
throw new PaymentFailed($exception->getMessage(), $exception->getCode());
|
||||
}
|
||||
}
|
102
app/PaymentDrivers/RazorpayPaymentDriver.php
Normal file
102
app/PaymentDrivers/RazorpayPaymentDriver.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers;
|
||||
|
||||
use App\Models\ClientGatewayToken;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PaymentHash;
|
||||
use App\Models\SystemLog;
|
||||
use App\PaymentDrivers\Razorpay\Hosted;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class RazorpayPaymentDriver extends BaseDriver
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
public $refundable = false;
|
||||
|
||||
public $token_billing = false;
|
||||
|
||||
public $can_authorise_credit_card = false;
|
||||
|
||||
public \Razorpay\Api\Api $gateway;
|
||||
|
||||
public $payment_method;
|
||||
|
||||
public static $methods = [
|
||||
GatewayType::HOSTED_PAGE => Hosted::class,
|
||||
];
|
||||
|
||||
const SYSTEM_LOG_TYPE = SystemLog::TYPE_RAZORPAY;
|
||||
|
||||
public function init(): self
|
||||
{
|
||||
$this->gateway = new \Razorpay\Api\Api(
|
||||
$this->company_gateway->getConfigField('apiKey'),
|
||||
$this->company_gateway->getConfigField('apiSecret'),
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function gatewayTypes(): array
|
||||
{
|
||||
return [
|
||||
GatewayType::HOSTED_PAGE,
|
||||
];
|
||||
}
|
||||
|
||||
public function setPaymentMethod($payment_method_id)
|
||||
{
|
||||
$class = self::$methods[$payment_method_id];
|
||||
|
||||
$this->payment_method = new $class($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function authorizeView(array $data)
|
||||
{
|
||||
return $this->payment_method->authorizeView($data);
|
||||
}
|
||||
|
||||
public function authorizeResponse($request)
|
||||
{
|
||||
return $this->payment_method->authorizeResponse($request);
|
||||
}
|
||||
|
||||
public function processPaymentView(array $data)
|
||||
{
|
||||
return $this->payment_method->paymentView($data);
|
||||
}
|
||||
|
||||
public function processPaymentResponse($request)
|
||||
{
|
||||
return $this->payment_method->paymentResponse($request);
|
||||
}
|
||||
|
||||
public function refund(Payment $payment, $amount, $return_client_response = false) {}
|
||||
|
||||
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) {}
|
||||
|
||||
/**
|
||||
* Convert the amount to the format that Razorpay supports.
|
||||
*
|
||||
* @param mixed|float $amount
|
||||
* @return int
|
||||
*/
|
||||
public function convertToRazorpayAmount($amount): int
|
||||
{
|
||||
return \number_format((float) $amount * 100, 0, '.', '');
|
||||
}
|
||||
}
|
@ -72,6 +72,7 @@
|
||||
"payfast/payfast-php-sdk": "^1.1",
|
||||
"pragmarx/google2fa": "^8.0",
|
||||
"predis/predis": "^1.1",
|
||||
"razorpay/razorpay": "2.*",
|
||||
"sentry/sentry-laravel": "^2",
|
||||
"square/square": "13.0.0.20210721",
|
||||
"stripe/stripe-php": "^7.50",
|
||||
|
126
composer.lock
generated
126
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "96908a391244cbc96eefbb130bd7bed9",
|
||||
"content-hash": "dc4f3d21b0f54361b6d4b85674fc900e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "apimatic/jsonmapper",
|
||||
@ -7789,6 +7789,68 @@
|
||||
],
|
||||
"time": "2021-09-25T23:10:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "razorpay/razorpay",
|
||||
"version": "2.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/razorpay/razorpay-php.git",
|
||||
"reference": "f562c919d153c343428c9a4e8d4e0848f334aef4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/razorpay/razorpay-php/zipball/f562c919d153c343428c9a4e8d4e0848f334aef4",
|
||||
"reference": "f562c919d153c343428c9a4e8d4e0848f334aef4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": ">=5.3.0",
|
||||
"rmccue/requests": "v1.8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.8|~5.0",
|
||||
"raveren/kint": "1.*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Razorpay\\Api\\": "src/",
|
||||
"Razorpay\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Abhay Rana",
|
||||
"email": "nemo@razorpay.com",
|
||||
"homepage": "https://captnemo.in",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Shashank Kumar",
|
||||
"email": "shashank@razorpay.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Razorpay PHP Client Library",
|
||||
"homepage": "https://docs.razorpay.com",
|
||||
"keywords": [
|
||||
"api",
|
||||
"client",
|
||||
"php",
|
||||
"razorpay"
|
||||
],
|
||||
"support": {
|
||||
"email": "contact@razorpay.com",
|
||||
"issues": "https://github.com/Razorpay/razorpay-php/issues",
|
||||
"source": "https://github.com/Razorpay/razorpay-php"
|
||||
},
|
||||
"time": "2021-09-16T06:18:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/promise",
|
||||
"version": "v2.8.0",
|
||||
@ -7839,6 +7901,66 @@
|
||||
},
|
||||
"time": "2020-05-12T15:16:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "rmccue/requests",
|
||||
"version": "v1.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/WordPress/Requests.git",
|
||||
"reference": "afbe4790e4def03581c4a0963a1e8aa01f6030f1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/WordPress/Requests/zipball/afbe4790e4def03581c4a0963a1e8aa01f6030f1",
|
||||
"reference": "afbe4790e4def03581c4a0963a1e8aa01f6030f1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7",
|
||||
"php-parallel-lint/php-console-highlighter": "^0.5.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3",
|
||||
"phpcompatibility/php-compatibility": "^9.0",
|
||||
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5",
|
||||
"requests/test-server": "dev-master",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"wp-coding-standards/wpcs": "^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Requests": "library/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"ISC"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ryan McCue",
|
||||
"homepage": "http://ryanmccue.info"
|
||||
}
|
||||
],
|
||||
"description": "A HTTP library written in PHP, for human beings.",
|
||||
"homepage": "http://github.com/WordPress/Requests",
|
||||
"keywords": [
|
||||
"curl",
|
||||
"fsockopen",
|
||||
"http",
|
||||
"idna",
|
||||
"ipv6",
|
||||
"iri",
|
||||
"sockets"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/WordPress/Requests/issues",
|
||||
"source": "https://github.com/WordPress/Requests/tree/v1.8.0"
|
||||
},
|
||||
"time": "2021-04-27T11:05:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sabre/uri",
|
||||
"version": "2.2.1",
|
||||
@ -15962,5 +16084,5 @@
|
||||
"platform-dev": {
|
||||
"php": "^7.3|^7.4|^8.0"
|
||||
},
|
||||
"plugin-api-version": "2.0.0"
|
||||
"plugin-api-version": "2.1.0"
|
||||
}
|
||||
|
33
database/migrations/2021_10_07_141737_razorpay.php
Normal file
33
database/migrations/2021_10_07_141737_razorpay.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Gateway;
|
||||
use App\Models\GatewayType;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class Razorpay extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$gateway = new Gateway();
|
||||
$gateway->id = 58;
|
||||
$gateway->name = 'Razorpay';
|
||||
$gateway->key = 'hxd6gwg3ekb9tb3v9lptgx1mqyg69zu9';
|
||||
$gateway->provider = 'Razorpay';
|
||||
$gateway->is_offsite = false;
|
||||
|
||||
$configuration = new \stdClass;
|
||||
$configuration->apiKey = '';
|
||||
$configuration->apiSecret = '';
|
||||
|
||||
$gateway->fields = \json_encode($configuration);
|
||||
$gateway->visible = true;
|
||||
$gateway->site_url = 'https://razorpay.com';
|
||||
$gateway->default_gateway_type_id = GatewayType::HOSTED_PAGE;
|
||||
$gateway->save();
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\PaymentType;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddHostedPageToPaymentTypes extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$type = new PaymentType();
|
||||
|
||||
$type->id = 35;
|
||||
$type->name = 'Hosted Page';
|
||||
$type->gateway_type_id = GatewayType::HOSTED_PAGE;
|
||||
|
||||
$type->save();
|
||||
}
|
||||
}
|
@ -81,6 +81,7 @@ class PaymentLibrariesSeeder extends Seeder
|
||||
['id' => 54, 'name' => 'PAYMILL', 'provider' => 'Paymill', 'key' => 'ca52f618a39367a4c944098ebf977e1c', 'fields' => '{"apiKey":""}'],
|
||||
['id' => 55, 'name' => 'Custom', 'provider' => 'Custom', 'is_offsite' => true, 'sort_order' => 21, 'key' => '54faab2ab6e3223dbe848b1686490baa', 'fields' => '{"name":"","text":""}'],
|
||||
['id' => 57, 'name' => 'Square', 'provider' => 'Square', 'is_offsite' => false, 'sort_order' => 21, 'key' => '65faab2ab6e3223dbe848b1686490baz', 'fields' => '{"accessToken":"","applicationId":"","locationId":"","testMode":false}'],
|
||||
['id' => 58, 'name' => 'Razorpay', 'provider' => 'Razorpay', 'is_offsite' => false, 'sort_order' => 21, 'key' => 'hxd6gwg3ekb9tb3v9lptgx1mqyg69zu9', 'fields' => '{"apiKey":"","apiSecret":""}'],
|
||||
];
|
||||
|
||||
foreach ($gateways as $gateway) {
|
||||
@ -97,7 +98,7 @@ class PaymentLibrariesSeeder extends Seeder
|
||||
|
||||
Gateway::query()->update(['visible' => 0]);
|
||||
|
||||
Gateway::whereIn('id', [1,7,11,15,20,39,46,55,50,57,52])->update(['visible' => 1]);
|
||||
Gateway::whereIn('id', [1,7,11,15,20,39,46,55,50,57,52,58])->update(['visible' => 1]);
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
Gateway::whereIn('id', [20])->update(['visible' => 0]);
|
||||
|
2
public/js/clients/payments/razorpay-aio.js
vendored
Normal file
2
public/js/clients/payments/razorpay-aio.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/*! For license information please see razorpay-aio.js.LICENSE.txt */
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=27)}({27:function(e,t,n){e.exports=n("tIvh")},tIvh:function(e,t){var n,r=JSON.parse(null===(n=document.querySelector("meta[name=razorpay-options]"))||void 0===n?void 0:n.content);r.handler=function(e){document.getElementById("razorpay_payment_id").value=e.razorpay_payment_id,document.getElementById("razorpay_signature").value=e.razorpay_signature,document.getElementById("server-response").submit()};var o=new Razorpay(r);document.getElementById("pay-now").onclick=function(e){e.target.parentElement.disabled=!0,o.open()}}});
|
9
public/js/clients/payments/razorpay-aio.js.LICENSE.txt
Normal file
9
public/js/clients/payments/razorpay-aio.js.LICENSE.txt
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
@ -15,6 +15,7 @@
|
||||
"/js/clients/payments/eway-credit-card.js": "/js/clients/payments/eway-credit-card.js?id=08ea84e9451abd434cff",
|
||||
"/js/clients/payments/mollie-credit-card.js": "/js/clients/payments/mollie-credit-card.js?id=73b66e88e2daabcd6549",
|
||||
"/js/clients/payments/paytrace-credit-card.js": "/js/clients/payments/paytrace-credit-card.js?id=c2b5f7831e1a46dd5fb2",
|
||||
"/js/clients/payments/razorpay-aio.js": "/js/clients/payments/razorpay-aio.js?id=817ab3b2b94ee37b14eb",
|
||||
"/js/clients/payments/square-credit-card.js": "/js/clients/payments/square-credit-card.js?id=070c86b293b532c5a56c",
|
||||
"/js/clients/payments/stripe-ach.js": "/js/clients/payments/stripe-ach.js?id=81c2623fc1e5769b51c7",
|
||||
"/js/clients/payments/stripe-alipay.js": "/js/clients/payments/stripe-alipay.js?id=665ddf663500767f1a17",
|
||||
|
29
resources/js/clients/payments/razorpay-aio.js
vendored
Normal file
29
resources/js/clients/payments/razorpay-aio.js
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
let options = JSON.parse(
|
||||
document.querySelector('meta[name=razorpay-options]')?.content
|
||||
);
|
||||
|
||||
options.handler = function(response) {
|
||||
document.getElementById('razorpay_payment_id').value =
|
||||
response.razorpay_payment_id;
|
||||
document.getElementById('razorpay_signature').value =
|
||||
response.razorpay_signature;
|
||||
document.getElementById('server-response').submit();
|
||||
};
|
||||
|
||||
let razorpay = new Razorpay(options);
|
||||
|
||||
document.getElementById('pay-now').onclick = function(event) {
|
||||
event.target.parentElement.disabled = true;
|
||||
|
||||
razorpay.open();
|
||||
};
|
@ -4317,6 +4317,7 @@ $LANG = array(
|
||||
'kbc_cbc' => 'KBC/CBC',
|
||||
'bancontact' => 'Bancontact',
|
||||
'ideal' => 'iDEAL',
|
||||
'aio_checkout' => 'All-in-one checkout',
|
||||
);
|
||||
|
||||
return $LANG;
|
||||
|
@ -0,0 +1,8 @@
|
||||
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.aio_checkout'), 'card_title' =>
|
||||
ctrans('texts.aio_checkout')])
|
||||
|
||||
@section('gateway_content')
|
||||
@component('portal.ninja2020.components.general.card-element-single')
|
||||
{{ __('texts.payment_method_cannot_be_preauthorized') }}
|
||||
@endcomponent
|
||||
@endsection
|
@ -0,0 +1,36 @@
|
||||
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.aio_checkout'), 'card_title' =>
|
||||
ctrans('texts.aio_checkout')])
|
||||
|
||||
@section('gateway_head')
|
||||
<meta name="razorpay-options" content="{{ \json_encode($options) }}">
|
||||
@endsection
|
||||
|
||||
@section('gateway_content')
|
||||
<form action="{{ route('client.payments.response') }}" method="post" id="server-response">
|
||||
@csrf
|
||||
<input type="hidden" name="gateway_response">
|
||||
<input type="hidden" name="store_card">
|
||||
<input type="hidden" name="payment_hash" value="{{ $payment_hash }}">
|
||||
|
||||
<input type="hidden" name="company_gateway_id" value="{{ $gateway->getCompanyGatewayId() }}">
|
||||
<input type="hidden" name="payment_method_id" value="{{ $payment_method_id }}">
|
||||
|
||||
<input type="hidden" name="razorpay_payment_id" id="razorpay_payment_id">
|
||||
<input type="hidden" name="razorpay_signature" id="razorpay_signature">
|
||||
</form>
|
||||
|
||||
<div class="alert alert-failure mb-4" hidden id="errors"></div>
|
||||
|
||||
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.payment_type')])
|
||||
{{ ctrans('texts.aio_checkout') }}
|
||||
@endcomponent
|
||||
|
||||
@include('portal.ninja2020.gateways.includes.payment_details')
|
||||
|
||||
@include('portal.ninja2020.gateways.includes.pay_now')
|
||||
@endsection
|
||||
|
||||
@section('gateway_footer')
|
||||
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
|
||||
<script src="{{ asset('js/clients/payments/razorpay-aio.js') }}"></script>
|
||||
@endsection
|
4
webpack.mix.js
vendored
4
webpack.mix.js
vendored
@ -106,6 +106,10 @@ mix.js("resources/js/app.js", "public/js")
|
||||
"resources/js/clients/statements/view.js",
|
||||
"public/js/clients/statements/view.js",
|
||||
)
|
||||
.js(
|
||||
"resources/js/clients/payments/razorpay-aio.js",
|
||||
"public/js/clients/payments/razorpay-aio.js"
|
||||
)
|
||||
|
||||
mix.copyDirectory('node_modules/card-js/card-js.min.css', 'public/css/card-js.min.css');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user