Merge pull request #6340 from turbo124/eway

Eway Payment Driver
This commit is contained in:
David Bomba 2021-07-27 15:42:07 +10:00 committed by GitHub
commit 83fbf55a32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1362 additions and 14 deletions

View File

@ -121,7 +121,7 @@ class EntitySentObject
ctrans( ctrans(
$this->template_subject, $this->template_subject,
[ [
'client' => $this->contact->present()->name(), 'client' => $this->contact->client->present()->name(),
'invoice' => $this->entity->number, 'invoice' => $this->entity->number,
] ]
); );
@ -133,7 +133,7 @@ class EntitySentObject
$this->template_body, $this->template_body,
[ [
'amount' => $this->getAmount(), 'amount' => $this->getAmount(),
'client' => $this->contact->present()->name(), 'client' => $this->contact->client->present()->name(),
'invoice' => $this->entity->number, 'invoice' => $this->entity->number,
] ]
); );

View File

@ -81,6 +81,9 @@ class Gateway extends StaticModel
case 1: case 1:
return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true]];//Authorize.net return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true]];//Authorize.net
break; break;
case 3:
return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true]];//eWay
break;
case 15: case 15:
return [GatewayType::PAYPAL => ['refund' => true, 'token_billing' => false]]; //Paypal return [GatewayType::PAYPAL => ['refund' => true, 'token_billing' => false]]; //Paypal
break; break;

View File

@ -68,7 +68,7 @@ class SystemLog extends Model
const TYPE_BRAINTREE = 307; const TYPE_BRAINTREE = 307;
const TYPE_WEPAY = 309; const TYPE_WEPAY = 309;
const TYPE_PAYFAST = 310; const TYPE_PAYFAST = 310;
const TYPE_EWAY = 311;
const TYPE_QUOTA_EXCEEDED = 400; const TYPE_QUOTA_EXCEEDED = 400;
const TYPE_UPSTREAM_FAILURE = 401; const TYPE_UPSTREAM_FAILURE = 401;

View File

@ -182,7 +182,6 @@ class User extends Authenticatable implements MustVerifyEmail
return $company_token->company; return $company_token->company;
} }
// return false; // return false;
throw new \Exception('No Company Found'); throw new \Exception('No Company Found');
//return Company::find(config('ninja.company_id')); //return Company::find(config('ninja.company_id'));

View File

@ -103,14 +103,14 @@ class EntitySentNotification extends Notification
"texts.notification_{$this->entity_name}_sent_subject", "texts.notification_{$this->entity_name}_sent_subject",
[ [
'amount' => $amount, 'amount' => $amount,
'client' => $this->contact->present()->name(), 'client' => $this->contact->client->present()->name(),
'invoice' => $this->entity->number, 'invoice' => $this->entity->number,
] ]
)) ))
->attachment(function ($attachment) use ($amount) { ->attachment(function ($attachment) use ($amount) {
$attachment->title(ctrans('texts.invoice_number_placeholder', ['invoice' => $this->entity->number]), $this->invitation->getAdminLink()) $attachment->title(ctrans('texts.invoice_number_placeholder', ['invoice' => $this->entity->number]), $this->invitation->getAdminLink())
->fields([ ->fields([
ctrans('texts.client') => $this->contact->present()->name(), ctrans('texts.client') => $this->contact->client->present()->name(),
ctrans('texts.amount') => $amount, ctrans('texts.amount') => $amount,
]); ]);
}); });

View File

@ -0,0 +1,185 @@
<?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://www.elastic.co/licensing/elastic-license
*/
namespace App\PaymentDrivers\Eway;
use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken;
use App\Models\GatewayType;
use App\Models\Payment;
use App\Models\PaymentHash;
use App\Models\PaymentType;
use App\Models\SystemLog;
use App\PaymentDrivers\EwayPaymentDriver;
use App\PaymentDrivers\Eway\ErrorCode;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
class CreditCard
{
public $eway_driver;
public function __construct(EwayPaymentDriver $eway_driver)
{
$this->eway_driver = $eway_driver;
}
public function authorizeView($data)
{
$data['gateway'] = $this->eway_driver;
$data['api_key'] = $this->eway_driver->company_gateway->getConfigField('apiKey');
$data['public_api_key'] = $this->eway_driver->company_gateway->getConfigField('publicApiKey');
return render('gateways.eway.authorize', $data);
}
/*
Eway\Rapid\Model\Response\CreateCustomerResponse {#2374 ▼
#fillable: array:16 [▶]
#errors: []
#attributes: array:11 [▼
"AuthorisationCode" => null
"ResponseCode" => "00"
"ResponseMessage" => "A2000"
"TransactionID" => null
"TransactionStatus" => false
"TransactionType" => "MOTO"
"BeagleScore" => null
"Verification" => Eway\Rapid\Model\Verification {#2553 ▼
#fillable: array:5 [▶]
#attributes: array:5 [▶]
}
"Customer" => Eway\Rapid\Model\Customer {#2504 ▼
#fillable: array:38 [▶]
#attributes: array:20 [▼
"CardDetails" => Eway\Rapid\Model\CardDetails {#2455 ▼
#fillable: array:8 [▶]
#attributes: array:7 [▼
"Number" => "411111XXXXXX1111"
"Name" => "Joey Diaz"
"ExpiryMonth" => "10"
"ExpiryYear" => "23"
"StartMonth" => null
"StartYear" => null
"IssueNumber" => null
]
}
"TokenCustomerID" => 917047257342
"Reference" => "A12345"
"Title" => "Mr."
"FirstName" => "John"
"LastName" => "Smith"
"CompanyName" => "Demo Shop 123"
"JobDescription" => "PHP Developer"
"Street1" => "Level 5"
"Street2" => "369 Queen Street"
"City" => "Sydney"
"State" => "NSW"
"PostalCode" => "2000"
"Country" => "au"
"Email" => "demo@example.org"
"Phone" => "09 889 0986"
"Mobile" => "09 889 6542"
"Comments" => ""
"Fax" => ""
"Url" => "http://www.ewaypayments.com"
]
}
"Payment" => Eway\Rapid\Model\Payment {#2564 ▼
#fillable: array:5 [▶]
#attributes: array:5 [▼
"TotalAmount" => 0
"InvoiceNumber" => ""
"InvoiceDescription" => ""
"InvoiceReference" => ""
"CurrencyCode" => "AUD"
]
}
"Errors" => null
]
}
*/
public function authorizeResponse($request)
{
$transaction = [
'Reference' => $this->eway_driver->client->number,
'Title' => '',
'FirstName' => $this->eway_driver->client->contacts()->first()->present()->last_name(),
'LastName' => $this->eway_driver->client->contacts()->first()->present()->first_name(),
'CompanyName' => $this->eway_driver->client->name,
'Street1' => $this->eway_driver->client->address1,
'Street2' => $this->eway_driver->client->address2,
'City' => $this->eway_driver->client->city,
'State' => $this->eway_driver->client->state,
'PostalCode' => $this->eway_driver->client->postal_code,
'Country' => $this->eway_driver->client->country->iso_3166_2,
'Phone' => $this->eway_driver->client->phone,
'Email' => $this->eway_driver->client->contacts()->first()->email,
"Url" => $this->eway_driver->client->website,
// 'Payment' => [
// 'TotalAmount' => 0,
// ],
// 'TransactionType' => \Eway\Rapid\Enum\TransactionType::PURCHASE,
'Method' => \Eway\Rapid\Enum\PaymentMethod::CREATE_TOKEN_CUSTOMER,
'SecuredCardData' => $request->input('SecuredCardData'),
];
$response = $this->eway_driver->init()->eway->createCustomer(\Eway\Rapid\Enum\ApiMethod::DIRECT, $transaction);
$response_status = ErrorCode::getStatus($response->ResponseMessage);
if(!$response_status['success'])
throw new PaymentFailed($response_status['message'], 400);
//success
$cgt = [];
$cgt['token'] = $response->Customer->TokenCustomerID;
$cgt['payment_method_id'] = GatewayType::CREDIT_CARD;
$payment_meta = new \stdClass;
$payment_meta->exp_month = $response->Customer->CardDetails->ExpiryMonth;
$payment_meta->exp_year = $response->Customer->CardDetails->ExpiryYear;
$payment_meta->brand = 'CC';
$payment_meta->last4 = substr($response->Customer->CardDetails->Number, -4);;
$payment_meta->type = GatewayType::CREDIT_CARD;
$cgt['payment_meta'] = $payment_meta;
$token = $this->eway_driver->storeGatewayToken($cgt, []);
return redirect()->route('client.payment_methods.index');
}
public function paymentView($data)
{
$data['gateway'] = $this->eway_driver;
$data['public_api_key'] = $this->eway_driver->company_gateway->getConfigField('publicApiKey');
return render('gateways.eway.pay', $data);
}
public function processPaymentResponse($request)
{
}
}

View File

@ -0,0 +1,105 @@
<?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://www.elastic.co/licensing/elastic-license
*/
namespace App\PaymentDrivers\Eway;
class ErrorCode
{
private static $success = [
"A2000" => "Transaction Approved",
"A2008" => "Honour With Identification",
"A2010" => "Approved For Partial Amount",
"A2011" => "Approved, VIP",
"A2016" => "Approved, Update Track 3",
];
private static $failure = [
"D4401" => "Refer to Issuer",
"D4402" => "Refer to Issuer, special",
"D4403" => "No Merchant",
"D4404" => "Pick Up Card",
"D4405" => "Do Not Honour",
"D4406" => "Error",
"D4407" => "Pick Up Card, Special",
"D4409" => "Request In Progress",
"D4412" => "Invalid Transaction",
"D4413" => "Invalid Amount",
"D4414" => "Invalid Card Number",
"D4415" => "No Issuer",
"D4417" => "3D Secure Error",
"D4419" => "Re-enter Last Transaction",
"D4421" => "No Action Taken",
"D4422" => "Suspected Malfunction",
"D4423" => "Unacceptable Transaction Fee",
"D4425" => "Unable to Locate Record On File",
"D4430" => "Format Error",
"D4431" => "Bank Not Supported By Switch",
"D4433" => "Expired Card, Capture",
"D4434" => "Suspected Fraud, Retain Card",
"D4435" => "Card Acceptor, Contact Acquirer, Retain Card",
"D4436" => "Restricted Card, Retain Card",
"D4437" => "Contact Acquirer Security Department, Retain Card",
"D4438" => "PIN Tries Exceeded, Capture",
"D4439" => "No Credit Account",
"D4440" => "Function Not Supported",
"D4441" => "Lost Card",
"D4442" => "No Universal Account",
"D4443" => "Stolen Card",
"D4444" => "No Investment Account",
"D4450" => "Click-to-Pay (Visa Checkout) Transaction",
"D4451" => "Insufficient Funds",
"D4452" => "No Cheque Account",
"D4453" => "No Savings Account",
"D4454" => "Expired Card",
"D4455" => "Incorrect PIN",
"D4456" => "No Card Record",
"D4457" => "Function Not Permitted to Cardholder",
"D4458" => "Function Not Permitted to Terminal",
"D4459" => "Suspected Fraud",
"D4460" => "Acceptor Contact Acquirer",
"D4461" => "Exceeds Withdrawal Limit",
"D4462" => "Restricted Card",
"D4463" => "Security Violation",
"D4464" => "Original Amount Incorrect",
"D4466" => "Acceptor Contact Acquirer, Security",
"D4467" => "Capture Card",
"D4475" => "PIN Tries Exceeded",
"D4476" => "Invalidate Txn Reference",
"D4481" => "Accumulated Transaction Counter (Amount) Exceeded",
"D4482" => "CVV Validation Error",
"D4483" => "Acquirer Is Not Accepting Transactions From You At This Time",
"D4484" => "Acquirer Is Not Accepting This Transaction",
"D4490" => "Cut off In Progress",
"D4491" => "Card Issuer Unavailable",
"D4492" => "Unable To Route Transaction",
"D4493" => "Cannot Complete, Violation Of The Law",
"D4494" => "Duplicate Transaction",
"D4495" => "Amex Declined",
"D4496" => "System Error",
"D4497" => "MasterPass Error",
"D4498" => "PayPal Create Transaction Error",
"D4499" => "Invalid Transaction for Auth/Void",
];
public static function getStatus($code)
{
if(array_key_exists($code, self::$success))
return ['success' => true, 'message' => self::$success[$code]];
if(array_key_exists($code, self::$failure))
return ['success' => false, 'message' => self::$failure[$code]];
return ['success' => false, 'message' => "Unknown error message code - {$code}"];
}
}

View File

@ -0,0 +1,111 @@
<?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://www.elastic.co/licensing/elastic-license
*/
namespace App\PaymentDrivers\Eway;
use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken;
use App\Models\GatewayType;
use App\Models\Payment;
use App\Models\PaymentHash;
use App\Models\PaymentType;
use App\Models\SystemLog;
use App\PaymentDrivers\EwayPaymentDriver;
use App\PaymentDrivers\Eway\ErrorCode;
use App\Utils\Traits\MakesHash;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
class Token
{
use MakesHash;
public $eway_driver;
public function __construct(EwayPaymentDriver $eway_driver)
{
$this->eway_driver = $eway_driver;
}
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
{
$amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total;
$transaction = [
'Customer' => [
'TokenCustomerID' => $cgt->token,
],
'Payment' => [
'TotalAmount' => $this->eway_driver->convertAmount($amount),
],
'TransactionType' => \Eway\Rapid\Enum\TransactionType::RECURRING,
];
$response = $this->eway_driver->init()->eway->createTransaction(\Eway\Rapid\Enum\ApiMethod::DIRECT, $transaction);
$response_status = ErrorCode::getStatus($response->ResponseMessage);
if(!$response_status['success'])
return $this->processUnsuccessfulPayment($response);
$payment = $this->processSuccessfulPayment($response);
return $payment;
}
private function processSuccessfulPayment($response)
{
$amount = array_sum(array_column($this->eway_driver->payment_hash->invoices(), 'amount')) + $this->eway_driver->payment_hash->fee_total;
$data = [
'gateway_type_id' => $cgt->gateway_type_id,
'payment_type' => GatewayType::CREDIT_CARD_OTHER,
'transaction_reference' => $response->Customer->Reference,
'amount' => $amount,
];
$payment = $this->eway_driver->createPayment($data);
$payment->meta = $cgt->meta;
$payment->save();
$payment_hash->payment_id = $payment->id;
$payment_hash->save();
return $payment;
}
private function processUnsuccessfulPayment($response)
{
$response_status = ErrorCode::getStatus($response->ResponseMessage);
$error = $response_status['message']
$error_code = $response->ResponseMessage;
$data = [
'response' => $response,
'error' => $error,
'error_code' => $error_code,
];
return $this->driver_class->processUnsuccessfulTransaction($data);
}
}

View File

@ -0,0 +1,198 @@
<?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://www.elastic.co/licensing/elastic-license
*/
namespace App\PaymentDrivers;
use App\Http\Requests\Payments\PaymentWebhookRequest;
use App\Models\ClientGatewayToken;
use App\Models\GatewayType;
use App\Models\Payment;
use App\Models\PaymentHash;
use App\Models\SystemLog;
use App\PaymentDrivers\Eway\CreditCard;
use App\PaymentDrivers\Eway\Token;
use App\Utils\Traits\MakesHash;
class EwayPaymentDriver extends BaseDriver
{
use MakesHash;
public $refundable = true; //does this gateway support refunds?
public $token_billing = true; //does this gateway support token billing?
public $can_authorise_credit_card = true; //does this gateway support authorizations?
public $eway; //initialized gateway
public $payment_method; //initialized payment method
public static $methods = [
GatewayType::CREDIT_CARD => CreditCard::class, //maps GatewayType => Implementation class
];
const SYSTEM_LOG_TYPE = SystemLog::TYPE_EWAY; //define a constant for your gateway ie TYPE_YOUR_CUSTOM_GATEWAY - set the const in the SystemLog model
public function init()
{
$apiKey = $this->company_gateway->getConfigField('apiKey');
$apiPassword = $this->company_gateway->getConfigField('password');
$apiEndpoint = $this->company_gateway->getConfigField('testMode') ? \Eway\Rapid\Client::MODE_SANDBOX : \Eway\Rapid\Client::MODE_PRODUCTION;
$this->eway = \Eway\Rapid::createClient($apiKey, $apiPassword, $apiEndpoint);
return $this;
}
/* Returns an array of gateway types for the payment gateway */
public function gatewayTypes(): array
{
$types = [];
$types[] = GatewayType::CREDIT_CARD;
return $types;
}
/* Sets the payment method initialized */
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); //this is your custom implementation from here
}
public function processPaymentResponse($request)
{
return $this->payment_method->paymentResponse($request); //this is your custom implementation from here
}
public function refund(Payment $payment, $amount, $return_client_response = false)
{
$refund = [
'Refund' => [
'TransactionID' => $payment->transaction_reference,
'TotalAmount' => $this->convertAmount($amount)
],
];
$response = $this->init()->eway->client->refund($refund);
$transaction_reference = '';
$refund_status = true;
$refund_message = '';
if ($response->TransactionStatus) {
$transaction_reference = $response->TransactionID;
} else {
if ($response->getErrors()) {
foreach ($response->getErrors() as $error) {
$refund_status = false;
$refund_message = \Eway\Rapid::getMessage($error);
}
} else {
$refund_status = false;
$refund_message 'Sorry, your refund failed';
}
}
return [
'transaction_reference' => $response->TransactionID,
'transaction_response' => json_encode($response),
'success' => $refund_status,
'description' => $refund_message,
'code' => '',
];
}
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
{
return (new Token($this))->tokenBilling($cgt, $payment_hash);
}
public function processWebhookRequest(PaymentWebhookRequest $request, Payment $payment = null)
{
}
public function convertAmount($amount)
{
$precision = $this->client->currency()->precision;
if($precision == 0)
return $amount;
if($precision == 1)
return $amount*10;
if$precision == 2)
return $amount*100;
return $amount;
}
public function getClientRequiredFields(): array
{
$fields = [];
$fields[] = ['name' => 'contact_first_name', 'label' => ctrans('texts.first_name'), 'type' => 'text', 'validation' => 'required'];
$fields[] = ['name' => 'contact_last_name', 'label' => ctrans('texts.last_name'), 'type' => 'text', 'validation' => 'required'];
$fields[] = ['name' => 'contact_email', 'label' => ctrans('texts.email'), 'type' => 'text', 'validation' => 'required,email:rfc'];
$fields[] = ['name' => 'client_country_id', 'label' => ctrans('texts.country'), 'type' => 'text', 'validation' => 'required'];
if ($this->company_gateway->require_client_name) {
$fields[] = ['name' => 'client_name', 'label' => ctrans('texts.client_name'), 'type' => 'text', 'validation' => 'required'];
}
// if ($this->company_gateway->require_contact_name) {
// }
// if ($this->company_gateway->require_contact_email) {
// }
if ($this->company_gateway->require_client_phone) {
$fields[] = ['name' => 'client_phone', 'label' => ctrans('texts.client_phone'), 'type' => 'tel', 'validation' => 'required'];
}
if ($this->company_gateway->require_billing_address) {
$fields[] = ['name' => 'client_address_line_1', 'label' => ctrans('texts.address1'), 'type' => 'text', 'validation' => 'required'];
$fields[] = ['name' => 'client_city', 'label' => ctrans('texts.city'), 'type' => 'text', 'validation' => 'required'];
$fields[] = ['name' => 'client_state', 'label' => ctrans('texts.state'), 'type' => 'text', 'validation' => 'required'];
}
if($this->company_gateway->require_postal_code)
$fields[] = ['name' => 'client_postal_code', 'label' => ctrans('texts.postal_code'), 'type' => 'text', 'validation' => 'required'];
if ($this->company_gateway->require_shipping_address) {
$fields[] = ['name' => 'client_shipping_address_line_1', 'label' => ctrans('texts.shipping_address1'), 'type' => 'text', 'validation' => 'required'];
$fields[] = ['name' => 'client_shipping_city', 'label' => ctrans('texts.shipping_city'), 'type' => 'text', 'validation' => 'required'];
$fields[] = ['name' => 'client_shipping_state', 'label' => ctrans('texts.shipping_state'), 'type' => 'text', 'validation' => 'required'];
$fields[] = ['name' => 'client_shipping_postal_code', 'label' => ctrans('texts.shipping_postal_code'), 'type' => 'text', 'validation' => 'required'];
$fields[] = ['name' => 'client_shipping_country_id', 'label' => ctrans('texts.shipping_country'), 'type' => 'text', 'validation' => 'required'];
}
return $fields;
}
}

View File

@ -0,0 +1,113 @@
<?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://www.elastic.co/licensing/elastic-license
*/
namespace App\PaymentDrivers\Eway;
use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken;
use App\Models\GatewayType;
use App\Models\Payment;
use App\Models\PaymentHash;
use App\Models\PaymentType;
use App\Models\SystemLog;
use App\Utils\Traits\MakesHash;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
class CreditCard
{
use MakesHash;
public $driver_class;
public function __construct(PaymentDriver $driver_class)
{
$this->driver_class = $driver_class;
}
public function authorizeView($data)
{
}
public function authorizeRequest($request)
{
}
public function paymentView($data)
{
}
public function processPaymentResponse($request)
{
}
/* This method is stubbed ready to go - you just need to harvest the equivalent 'transaction_reference' */
private function processSuccessfulPayment($response)
{
$amount = array_sum(array_column($this->driver_class->payment_hash->invoices(), 'amount')) + $this->driver_class->payment_hash->fee_total;
$payment_record = [];
$payment_record['amount'] = $amount;
$payment_record['payment_type'] = PaymentType::CREDIT_CARD_OTHER;
$payment_record['gateway_type_id'] = GatewayType::CREDIT_CARD;
// $payment_record['transaction_reference'] = $response->transaction_id;
$payment = $this->driver_class->createPayment($payment_record, Payment::STATUS_COMPLETED);
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
}
private function processUnsuccessfulPayment($response)
{
/*Harvest your own errors here*/
// $error = $response->status_message;
// if(property_exists($response, 'approval_message') && $response->approval_message)
// $error .= " - {$response->approval_message}";
// $error_code = property_exists($response, 'approval_message') ? $response->approval_message : 'Undefined code';
$data = [
'response' => $response,
'error' => $error,
'error_code' => $error_code,
];
return $this->driver_class->processUnsuccessfulTransaction($data);
}
/* Helpers */
/*
You will need some helpers to handle successful and unsuccessful responses
Some considerations after a succesful transaction include:
Logging of events: success +/- failure
Recording a payment
Notifications
*/
}

View File

@ -17,10 +17,9 @@ use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
use App\Models\PaymentHash; use App\Models\PaymentHash;
use App\Models\SystemLog; use App\Models\SystemLog;
use App\PaymentDrivers\Stripe\CreditCard;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
class DriverTemplate extends BaseDriver class PaymentDriver extends BaseDriver
{ {
use MakesHash; use MakesHash;
@ -85,12 +84,12 @@ class DriverTemplate extends BaseDriver
public function refund(Payment $payment, $amount, $return_client_response = false) public function refund(Payment $payment, $amount, $return_client_response = false)
{ {
return $this->payment_method->yourRefundImplementationHere(); //this is your custom implementation from here //this is your custom implementation from here
} }
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
{ {
return $this->payment_method->yourTokenBillingImplmentation(); //this is your custom implementation from here //this is your custom implementation from here
} }
public function processWebhookRequest(PaymentWebhookRequest $request, Payment $payment = null) public function processWebhookRequest(PaymentWebhookRequest $request, Payment $payment = null)

View File

@ -0,0 +1,34 @@
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.credit_card'), 'card_title' => ctrans('texts.credit_card')])
@section('gateway_head')
@endsection
@section('gateway_content')
<form action="{{ $payment_endpoint_url }}" method="post" id="server_response">
@if(!Request::isSecure())
<p class="alert alert-failure">{{ ctrans('texts.https_required') }}</p>
@endif
<div class="alert alert-failure mb-4" hidden id="errors"></div>
<!-- This is a generic credit card component utilizing CardJS -->
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.method')])
{{ ctrans('texts.credit_card') }}
@endcomponent
<div class="bg-white px-4 py-5 flex justify-end">
<button
type="submit"
id="{{ $id ?? 'pay-now' }}"
class="button button-primary bg-primary {{ $class ?? '' }}">
<span>{{ ctrans('texts.add_payment_method') }}</span>
</button>
</div>
</form>
@endsection
@section('gateway_footer')
<!-- Your JS includes go here -->
@endsection

View File

@ -0,0 +1,64 @@
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.credit_card'), 'card_title' => ctrans('texts.credit_card')])
@section('gateway_head')
@endsection
@section('gateway_content')
<form action="{{ $payment_endpoint_url }}" method="post" id="server_response">
<div class="alert alert-failure mb-4" hidden id="errors"></div>
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.method')])
{{ ctrans('texts.credit_card') }}
@endcomponent
@include('portal.ninja2020.gateways.includes.payment_details')
<-- If there are existing tokens available these are displayed here for you -->
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')])
@if(count($tokens) > 0)
@foreach($tokens as $token)
<label class="mr-4">
<input
type="radio"
data-token="{{ $token->token }}"
name="payment-type"
class="form-radio cursor-pointer toggle-payment-with-token"/>
<span class="ml-1 cursor-pointer">**** {{ optional($token->meta)->last4 }}</span>
</label>
@endforeach
@endisset
<label>
<input
type="radio"
id="toggle-payment-with-credit-card"
class="form-radio cursor-pointer"
name="payment-type"
checked/>
<span class="ml-1 cursor-pointer">{{ __('texts.new_card') }}</span>
</label>
@endcomponent
<!-- This include gives the options to save the payment method -->
@include('portal.ninja2020.gateways.includes.save_card')
<!-- This include pops up a credit card form -->
@include('portal.ninja2020.gateways.wepay.includes.credit_card')
@include('portal.ninja2020.gateways.includes.pay_now')
</form>
@endsection
@section('gateway_footer')
<script>
document.getElementById('pay-now').addEventListener('click', function() {
document.getElementById('server_response').submit();
});
</script>
@endsection

View File

@ -41,6 +41,7 @@
"codedge/laravel-selfupdater": "^3.2", "codedge/laravel-selfupdater": "^3.2",
"composer/composer": "^2", "composer/composer": "^2",
"doctrine/dbal": "^2.10", "doctrine/dbal": "^2.10",
"eway/eway-rapid-php": "^1.3",
"fakerphp/faker": "^1.14", "fakerphp/faker": "^1.14",
"fideloper/proxy": "^4.2", "fideloper/proxy": "^4.2",
"fruitcake/laravel-cors": "^2.0", "fruitcake/laravel-cors": "^2.0",

60
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "d2beb37ff5fbee59ad4bb792e944eb10", "content-hash": "c9f7d76428c6f556ae531570b7761bf5",
"packages": [ "packages": [
{ {
"name": "asm/php-ansible", "name": "asm/php-ansible",
@ -1964,6 +1964,62 @@
], ],
"time": "2020-12-29T14:50:06+00:00" "time": "2020-12-29T14:50:06+00:00"
}, },
{
"name": "eway/eway-rapid-php",
"version": "v1.3.4",
"source": {
"type": "git",
"url": "https://github.com/eWAYPayment/eway-rapid-php.git",
"reference": "5b765d83ef69e1783f391ae85aed48d47dd5f8eb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/eWAYPayment/eway-rapid-php/zipball/5b765d83ef69e1783f391ae85aed48d47dd5f8eb",
"reference": "5b765d83ef69e1783f391ae85aed48d47dd5f8eb",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"php": ">=5.4.0"
},
"require-dev": {
"internations/http-mock": "~0.7",
"jeremeamia/superclosure": "1.0.2",
"phpdocumentor/phpdocumentor": "~2.8",
"phpunit/phpunit": "4.8.*",
"squizlabs/php_codesniffer": "2.*"
},
"type": "library",
"autoload": {
"psr-4": {
"Eway\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "eWAY",
"homepage": "https://www.eway.com.au"
}
],
"description": "eWAY Rapid PHP library",
"homepage": "https://www.eway.com.au",
"keywords": [
"eway",
"payment processing",
"payments",
"rapid"
],
"support": {
"issues": "https://github.com/eWAYPayment/eway-rapid-php/issues",
"source": "https://github.com/eWAYPayment/eway-rapid-php/tree/master"
},
"time": "2016-09-12T05:46:41+00:00"
},
{ {
"name": "fakerphp/faker", "name": "fakerphp/faker",
"version": "v1.15.0", "version": "v1.15.0",
@ -14881,5 +14937,5 @@
"platform-dev": { "platform-dev": {
"php": "^7.3|^7.4|^8.0" "php": "^7.3|^7.4|^8.0"
}, },
"plugin-api-version": "2.1.0" "plugin-api-version": "2.0.0"
} }

View File

@ -0,0 +1,40 @@
<?php
use App\Models\Gateway;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class ActivateEwayPaymentDriver extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if($eway = Gateway::find(3))
{
$eway->visible = true;
$eway->provider = 'Eway';
$fields = json_decode($eway->fields);
$fields->publicApiKey = '';
$eway->fields = json_encode($fields);
$eway->save();
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}

View File

@ -27,7 +27,7 @@ class PaymentLibrariesSeeder extends Seeder
'], '],
['id' => 2, 'name' => 'CardSave', 'provider' => 'CardSave', 'key' => '46c5c1fed2c43acf4f379bae9c8b9f76', 'fields' => '{"merchantId":"","password":""} ['id' => 2, 'name' => 'CardSave', 'provider' => 'CardSave', 'key' => '46c5c1fed2c43acf4f379bae9c8b9f76', 'fields' => '{"merchantId":"","password":""}
'], '],
['id' => 3, 'name' => 'Eway Rapid', 'provider' => 'Eway_RapidShared', 'is_offsite' => true, 'key' => '944c20175bbe6b9972c05bcfe294c2c7', 'fields' => '{"apiKey":"","password":"","testMode":false}'], ['id' => 3, 'name' => 'Eway Rapid', 'provider' => 'Eway', 'is_offsite' => true, 'key' => '944c20175bbe6b9972c05bcfe294c2c7', 'fields' => '{"apiKey":"","password":"","publicApiKey":"","testMode":false}'],
['id' => 4, 'name' => 'FirstData Connect', 'provider' => 'FirstData_Connect', 'key' => '4e0ed0d34552e6cb433506d1ac03a418', 'fields' => '{"storeId":"","sharedSecret":"","testMode":false}'], ['id' => 4, 'name' => 'FirstData Connect', 'provider' => 'FirstData_Connect', 'key' => '4e0ed0d34552e6cb433506d1ac03a418', 'fields' => '{"storeId":"","sharedSecret":"","testMode":false}'],
['id' => 5, 'name' => 'Migs ThreeParty', 'provider' => 'Migs_ThreeParty', 'key' => '513cdc81444c87c4b07258bc2858d3fa', 'fields' => '{"merchantId":"","merchantAccessCode":"","secureHash":""}'], ['id' => 5, 'name' => 'Migs ThreeParty', 'provider' => 'Migs_ThreeParty', 'key' => '513cdc81444c87c4b07258bc2858d3fa', 'fields' => '{"merchantId":"","merchantAccessCode":"","secureHash":""}'],
['id' => 6, 'name' => 'Migs TwoParty', 'provider' => 'Migs_TwoParty', 'key' => '99c2a271b5088951334d1302e038c01a', 'fields' => '{"merchantId":"","merchantAccessCode":"","secureHash":""}'], ['id' => 6, 'name' => 'Migs TwoParty', 'provider' => 'Migs_TwoParty', 'key' => '99c2a271b5088951334d1302e038c01a', 'fields' => '{"merchantId":"","merchantAccessCode":"","secureHash":""}'],
@ -96,7 +96,7 @@ class PaymentLibrariesSeeder extends Seeder
Gateway::query()->update(['visible' => 0]); Gateway::query()->update(['visible' => 0]);
Gateway::whereIn('id', [1,15,20,39,55,50])->update(['visible' => 1]); Gateway::whereIn('id', [1,3,15,20,39,55,50])->update(['visible' => 1]);
if (Ninja::isHosted()) { if (Ninja::isHosted()) {
Gateway::whereIn('id', [20])->update(['visible' => 0]); Gateway::whereIn('id', [20])->update(['visible' => 0]);

View File

@ -0,0 +1,57 @@
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.credit_card'), 'card_title' =>
ctrans('texts.credit_card')])
@section('gateway_head')
@endsection
@section('gateway_content')
<form action="{{ route('client.payment_methods.store', ['method' => App\Models\GatewayType::CREDIT_CARD]) }}"
method="post" id="payment_form">
@csrf
<input type="hidden" id="securefieldcode" name="SecuredCardData" value="" />
<input type="hidden" name="company_gateway_id" value="{{ $gateway->company_gateway->id }}">
<input type="hidden" name="payment_method_id" value="1">
@if (!Request::isSecure())
<p class="alert alert-failure">{{ ctrans('texts.https_required') }}</p>
@endif
<div class="alert alert-failure mb-4" hidden id="errors"></div>
<!-- This is a generic credit card component utilizing CardJS -->
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.method')])
{{ ctrans('texts.credit_card') }}
@endcomponent
<div id="eway-secure-panel"></div>
@component('portal.ninja2020.gateways.includes.pay_now', ['id' => 'authorize-card'])
{{ ctrans('texts.add_payment_method') }}
@endcomponent
</form>
@endsection
@section('gateway_footer')
<!-- Your JS includes go here -->
<script src="https://secure.ewaypayments.com/scripts/eWAY.min.js" data-init="false"></script>
@include('portal.ninja2020.gateways.eway.includes.credt_card')
<script type="text/javascript">
window.onload = function() {
eWAY.setupSecureField(groupFieldConfig, securePanelCallback);
};
document
.getElementById('authorize-card')
.addEventListener('click', () => {
saveAndSubmit();
});
</script>
@endsection

View File

@ -0,0 +1,289 @@
<script type="text/javascript">
var labelStyles = "padding-right: 20px; float: right;";
var publicApiKey = "{{ $public_api_key }}";
var cardStyles = "padding: 2px; border: 1px solid #AAA; border-radius: 3px; height: 34px; width: 100%;";
var rowStyles = "";
var groupStyles = "";
var groupFieldConfig = {
publicApiKey: publicApiKey,
fieldDivId: "eway-secure-panel",
fieldType: "group",
styles: groupStyles,
layout : {
fonts: [
"Lobster"
],
rows : [
{
styles: rowStyles,
cells: [
{
colSpan: 12,
styles: "margin-top: 15px;",
label: {
fieldColSpan: 4,
text: "Card Name:",
styles: "",
},
field: {
fieldColSpan: 8,
fieldType: "name",
styles: cardStyles,
divStyles: "padding-left: 10px;"
}
},
{
colSpan: 12,
styles: "margin-top: 15px;",
label: {
fieldColSpan: 4,
text: "Expiry:",
styles: "",
},
field: {
fieldColSpan: 8,
fieldType: "expirytext",
styles: cardStyles,
divStyles: "padding-left: 10px;"
}
}
]
},
{
styles: rowStyles,
cells: [
{
colSpan: 12,
styles: "margin-top: 15px;",
label: {
fieldColSpan: 4,
text: "Card Number:",
styles: "",
},
field: {
fieldColSpan: 8,
fieldType: "card",
styles: cardStyles,
}
},
{
colSpan: 12,
styles: "margin-top: 15px;",
label: {
fieldColSpan: 4,
text: "CVV Number:",
styles: "",
},
field: {
fieldColSpan: 8,
fieldType: "cvn",
styles: cardStyles,
}
}
]
}
]
}
};
function securePanelCallback(event) {
if (!event.fieldValid) {
alert(getError(event.errors));
} else {
var s = document.getElementById("securefieldcode");
s.value = event.secureFieldCode
}
}
function doneCallback() {
var form = document.getElementById("payment_form");
form.submit();
}
function saveAndSubmit() {
eWAY.saveAllFields(doneCallback, 2000);
return false;
}
function getError(k){
myArr = k.split(" ");
var str = "";
for(error in myArr){
str = str.concat(map.get(myArr[error])) + '\n';
}
return str;
}
const map = new Map();
map.set('V6000', 'Validation error');
map.set('V6001', 'Invalid CustomerIP');
map.set('V6002', 'Invalid DeviceID');
map.set('V6003', 'Invalid Request PartnerID');
map.set('V6004', 'Invalid Request Method');
map.set('V6010', 'Invalid TransactionType, account not certified for eCome only MOTO or Recurring available');
map.set('V6011', 'Invalid Payment TotalAmount');
map.set('V6012', 'Invalid Payment InvoiceDescription');
map.set('V6013', 'Invalid Payment InvoiceNumber');
map.set('V6014', 'Invalid Payment InvoiceReference');
map.set('V6015', 'Invalid Payment CurrencyCode');
map.set('V6016', 'Payment Required');
map.set('V6017', 'Payment CurrencyCode Required');
map.set('V6018', 'Unknown Payment CurrencyCode');
map.set('V6019', 'Cardholder identity authentication required');
map.set('V6020', 'Cardholder Input Required');
map.set('V6021', 'EWAY_CARDHOLDERNAME Required');
map.set('V6022', 'EWAY_CARDNUMBER Required');
map.set('V6023', 'EWAY_CARDCVN Required');
map.set('V6024', 'Cardholder Identity Authentication One Time Password Not Active Yet');
map.set('V6025', 'PIN Required');
map.set('V6033', 'Invalid Expiry Date');
map.set('V6034', 'Invalid Issue Number');
map.set('V6035', 'Invalid Valid From Date');
map.set('V6039', 'Invalid Network Token Status');
map.set('V6040', 'Invalid TokenCustomerID');
map.set('V6041', 'Customer Required');
map.set('V6042', 'Customer FirstName Required');
map.set('V6043', 'Customer LastName Required');
map.set('V6044', 'Customer CountryCode Required');
map.set('V6045', 'Customer Title Required');
map.set('V6046', 'TokenCustomerID Required');
map.set('V6047', 'RedirectURL Required');
map.set('V6048', 'CheckoutURL Required when CheckoutPayment specified');
map.set('V6049', 'nvalid Checkout URL');
map.set('V6051', 'Invalid Customer FirstName');
map.set('V6052', 'Invalid Customer LastName');
map.set('V6053', 'Invalid Customer CountryCode');
map.set('V6058', 'Invalid Customer Title');
map.set('V6059', 'Invalid RedirectURL');
map.set('V6060', 'Invalid TokenCustomerID');
map.set('V6061', 'Invalid Customer Reference');
map.set('V6062', 'Invalid Customer CompanyName');
map.set('V6063', 'Invalid Customer JobDescription');
map.set('V6064', 'Invalid Customer Street1');
map.set('V6065', 'Invalid Customer Street2');
map.set('V6066', 'Invalid Customer City');
map.set('V6067', 'Invalid Customer State');
map.set('V6068', 'Invalid Customer PostalCode');
map.set('V6069', 'Invalid Customer Email');
map.set('V6070', 'Invalid Customer Phone');
map.set('V6071', 'Invalid Customer Mobile');
map.set('V6072', 'Invalid Customer Comments');
map.set('V6073', 'Invalid Customer Fax');
map.set('V6074', 'Invalid Customer URL');
map.set('V6075', 'Invalid ShippingAddress FirstName');
map.set('V6076', 'Invalid ShippingAddress LastName');
map.set('V6077', 'Invalid ShippingAddress Street1');
map.set('V6078', 'Invalid ShippingAddress Street2');
map.set('V6079', 'Invalid ShippingAddress City');
map.set('V6080', 'Invalid ShippingAddress State');
map.set('V6081', 'Invalid ShippingAddress PostalCode');
map.set('V6082', 'Invalid ShippingAddress Email');
map.set('V6083', 'Invalid ShippingAddress Phone');
map.set('V6084', 'Invalid ShippingAddress Country');
map.set('V6085', 'Invalid ShippingAddress ShippingMethod');
map.set('V6086', 'Invalid ShippingAddress Fax');
map.set('V6091', 'Unknown Customer CountryCode');
map.set('V6092', 'Unknown ShippingAddress CountryCode');
map.set('V6093', 'Insufficient Address Information');
map.set('V6100', 'Invalid EWAY_CARDNAME');
map.set('V6101', 'Invalid EWAY_CARDEXPIRYMONTH');
map.set('V6102', 'Invalid EWAY_CARDEXPIRYYEAR');
map.set('V6103', 'Invalid EWAY_CARDSTARTMONTH');
map.set('V6104', 'Invalid EWAY_CARDSTARTYEAR');
map.set('V6105', 'Invalid EWAY_CARDISSUENUMBER');
map.set('V6106', 'Invalid EWAY_CARDCVN');
map.set('V6107', 'Invalid EWAY_ACCESSCODE');
map.set('V6108', 'Invalid CustomerHostAddress');
map.set('V6109', 'Invalid UserAgent');
map.set('V6110', 'Invalid EWAY_CARDNUMBER');
map.set('V6111', 'Unauthorised API Access, Account Not PCI Certified');
map.set('V6112', 'Redundant card details other than expiry year and month');
map.set('V6113', 'Invalid transaction for refund');
map.set('V6114', 'Gateway validation error');
map.set('V6115', 'Invalid DirectRefundRequest, Transaction ID');
map.set('V6116', 'Invalid card data on original TransactionID');
map.set('V6117', 'Invalid CreateAccessCodeSharedRequest, FooterText');
map.set('V6118', 'Invalid CreateAccessCodeSharedRequest, HeaderText');
map.set('V6119', 'Invalid CreateAccessCodeSharedRequest, Language');
map.set('V6120', 'Invalid CreateAccessCodeSharedRequest, LogoUrl');
map.set('V6121', 'Invalid TransactionSearch, Filter Match Type');
map.set('V6122', 'Invalid TransactionSearch, Non numeric Transaction ID');
map.set('V6123', 'Invalid TransactionSearch,no TransactionID or AccessCode specified');
map.set('V6124', 'Invalid Line Items. The line items have been provided however the totals do not match the TotalAmount field');
map.set('V6125', 'Selected Payment Type not enabled');
map.set('V6126', 'Invalid encrypted card number, decryption failed');
map.set('V6127', 'Invalid encrypted cvn, decryption failed');
map.set('V6128', 'Invalid Method for Payment Type');
map.set('V6129', 'Transaction has not been authorised for Capture/Cancellation');
map.set('V6130', 'Generic customer information error');
map.set('V6131', 'Generic shipping information error');
map.set('V6132', 'Transaction has already been completed or voided, operation not permitted');
map.set('V6133', 'Checkout not available for Payment Type');
map.set('V6134', 'Invalid Auth Transaction ID for Capture/Void');
map.set('V6135', 'PayPal Error Processing Refund');
map.set('V6136', 'Original transaction does not exist or state is incorrect');
map.set('V6140', 'Merchant account is suspended');
map.set('V6141', 'Invalid PayPal account details or API signature');
map.set('V6142', 'Authorise not available for Bank/Branch');
map.set('V6143', 'Invalid Public Key');
map.set('V6144', 'Method not available with Public API Key Authentication');
map.set('V6145', 'Credit Card not allow if Token Customer ID is provided with Public API Key Authentication');
map.set('V6146', 'Client Side Encryption Key Missing or Invalid');
map.set('V6147', 'Unable to Create One Time Code for Secure Field');
map.set('V6148', 'Secure Field has Expired');
map.set('V6149', 'Invalid Secure Field One Time Code');
map.set('V6150', 'Invalid Refund Amount');
map.set('V6151', 'Refund amount greater than original transaction');
map.set('V6152', 'Original transaction already refunded for total amount');
map.set('V6153', 'Card type not support by merchant');
map.set('V6154', 'Insufficent Funds Available For Refund');
map.set('V6155', 'Missing one or more fields in request');
map.set('V6160', 'Encryption Method Not Supported');
map.set('V6161', 'Encryption failed, missing or invalid key');
map.set('V6165', 'Invalid Click-to-Pay (Visa Checkout) data or decryption failed');
map.set('V6170', 'Invalid TransactionSearch, Invoice Number is not unique');
map.set('V6171', 'Invalid TransactionSearch, Invoice Number not found');
map.set('V6220', 'Three domain secure XID invalid');
map.set('V6221', 'Three domain secure ECI invalid');
map.set('V6222', 'Three domain secure AVV invalid');
map.set('V6223', 'Three domain secure XID is required');
map.set('V6224', 'Three Domain Secure ECI is required');
map.set('V6225', 'Three Domain Secure AVV is required');
map.set('V6226', 'Three Domain Secure AuthStatus is required');
map.set('V6227', 'Three Domain Secure AuthStatus invalid');
map.set('V6228', 'Three domain secure Version is required');
map.set('V6230', 'Three domain secure Directory Server Txn ID invalid');
map.set('V6231', 'Three domain secure Directory Server Txn ID is required');
map.set('V6232', 'Three domain secure Version is invalid');
map.set('V6501', 'Invalid Amex InstallementPlan');
map.set('V6502', 'Invalid Number Of Installements for Amex. Valid values are from 0 to 99 inclusive');
map.set('V6503', 'Merchant Amex ID required');
map.set('V6504', 'Invalid Merchant Amex ID');
map.set('V6505', 'Merchant Terminal ID required');
map.set('V6506', 'Merchant category code required');
map.set('V6507', 'Invalid merchant category code');
map.set('V6508', 'Amex 3D ECI required');
map.set('V6509', 'Invalid Amex 3D ECI');
map.set('V6510', 'Invalid Amex 3D verification value');
map.set('V6511', 'Invalid merchant location data');
map.set('V6512', 'Invalid merchant street address');
map.set('V6513', 'Invalid merchant city');
map.set('V6514', 'Invalid merchant country');
map.set('V6515', 'Invalid merchant phone');
map.set('V6516', 'Invalid merchant postcode');
map.set('V6517', 'Amex connection error');
map.set('V6518', 'Amex EC Card Details API returned invalid data');
map.set('V6520', 'Invalid or missing Amex Point Of Sale Data');
map.set('V6521', 'Invalid or missing Amex transaction date time');
map.set('V6522', 'Invalid or missing Amex Original transaction date time');
map.set('V6530', 'Credit Card Number in non Credit Card Field');
</script>

View File

@ -0,0 +1,94 @@
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.credit_card'), 'card_title' => ctrans('texts.credit_card')])
@section('gateway_head')
@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" id="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="1">
<input type="hidden" name="token" id="token" value="">
</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.credit_card') }}
@endcomponent
@include('portal.ninja2020.gateways.includes.payment_details')
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')])
@if(count($tokens) > 0)
@foreach($tokens as $token)
<label class="mr-4">
<input
type="radio"
data-token="{{ $token->token }}"
name="payment-type"
class="form-radio cursor-pointer toggle-payment-with-token"/>
<span class="ml-1 cursor-pointer">**** {{ optional($token->meta)->last4 }}</span>
</label>
@endforeach
@endisset
<label>
<input
type="radio"
id="toggle-payment-with-credit-card"
class="form-radio cursor-pointer"
name="payment-type"
checked/>
<span class="ml-1 cursor-pointer">{{ __('texts.new_card') }}</span>
</label>
@endcomponent
<div id="eway-secure-panel">
@include('portal.ninja2020.gateways.includes.save_card')
</div>
<!-- -->
@include('portal.ninja2020.gateways.includes.pay_now')
@endsection
@section('gateway_footer')
@include('portal.ninja2020.gateways.eway.includes.credit_card')
<script src="https://secure.ewaypayments.com/scripts/eWAY.min.js" data-init="false"></script>
<script type="text/javascript">
window.onload = function() {
eWAY.setupSecureField(groupFieldConfig, securePanelCallback);
};
document.getElementById('eway-secure-panel').hidden = true;
Array
.from(document.getElementsByClassName('toggle-payment-with-token'))
.forEach((element) => element.addEventListener('click', (e) => {
document.getElementById('save-card--container').style.display = 'none';
document.getElementById('eway-secure-panel').style.display = 'none';
document.getElementById('token').value = e.target.dataset.token;
}));
document
.getElementById('toggle-payment-with-credit-card')
.addEventListener('click', (e) => {
document.getElementById('save-card--container').style.display = 'grid';
document.getElementById('eway-secure-panel').style.display = 'flex';
document.getElementById('token').value = null;
});
</script>
@endsection