Merge branch 'upgrade_square_implementation' into v5-develop

This commit is contained in:
David Bomba 2023-08-20 19:17:41 +10:00
commit dfb19f9d4a
12 changed files with 768 additions and 85 deletions

View File

@ -51,7 +51,7 @@ class NinjaMailerJob implements ShouldQueue
public $override;
/** @var \App\Models\Company $company | null **/
/** @var null|\App\Models\Company $company **/
public ?Company $company;
private $mailer;
@ -143,8 +143,6 @@ class NinjaMailerJob implements ShouldQueue
LightLogs::create(new EmailSuccess($this->nmo->company->company_key))
->send();
$this->nmo = null;
$this->company = null;
} catch(\Symfony\Component\Mime\Exception\RfcComplianceException $e) {
nlog("Mailer failed with a Logic Exception {$e->getMessage()}");
$this->fail();
@ -195,6 +193,9 @@ class NinjaMailerJob implements ShouldQueue
$this->release($this->backoff()[$this->attempts()-1]);
}
$this->nmo = null;
$this->company = null;
/*Clean up mailers*/
$this->cleanUpMailers();
}

View File

@ -221,6 +221,22 @@ class CompanyGateway extends BaseModel
{
$this->config = encrypt(json_encode($config));
}
/**
* setConfigField
*
* @param mixed $field
* @param mixed $value
* @return void
*/
public function setConfigField($field, $value): void
{
$config = $this->getConfig();
$config->{$field} = $value;
$this->setConfig($config);
$this->save();
}
/**
* @return mixed

View File

@ -171,7 +171,7 @@ class Gateway extends StaticModel
];
case 57:
return [
GatewayType::CREDIT_CARD => ['refund' => false, 'token_billing' => true], //Square
GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true], //Square
];
case 52:
return [

View File

@ -17,7 +17,7 @@ use Illuminate\Database\Eloquent\Model;
* App\Models\PaymentHash
*
* @property int $id
* @property string $hash
* @property string $hash 32 char length AlphaNum
* @property float $fee_total
* @property int|null $fee_invoice_id
* @property \stdClass $data
@ -41,6 +41,7 @@ class PaymentHash extends Model
/**
* @class \App\Models\PaymentHash $this
* @property \App\Models\PaymentHash $data
* @property \App\Modes\PaymentHash $hash 32 char length AlphaNum
* @class \stdClass $data
* @property string $raw_value
*/

View File

@ -263,6 +263,8 @@ class BaseDriver extends AbstractPaymentDriver
public function setClient(Client $client)
{
$this->client = $client;
return $this;
}
/************************** Helper methods *************************************/

View File

@ -12,6 +12,7 @@
namespace App\PaymentDrivers\Square;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\SystemLog;
use Illuminate\View\View;
@ -33,11 +34,8 @@ class CreditCard implements MethodInterface
{
use MakesHash;
public $square_driver;
public function __construct(SquarePaymentDriver $square_driver)
public function __construct(public SquarePaymentDriver $square_driver)
{
$this->square_driver = $square_driver;
$this->square_driver->init();
}
@ -102,28 +100,35 @@ class CreditCard implements MethodInterface
);
if ($request->shouldUseToken()) {
/** @var \App\Models\ClientGatewayToken $cgt **/
$cgt = ClientGatewayToken::where('token', $request->token)->first();
$cgt = ClientGatewayToken::query()->where('token', $request->token)->first();
$token = $cgt->token;
}
$invoice = Invoice::query()->whereIn('id', $this->transformKeys(array_column($this->square_driver->payment_hash->invoices(), 'invoice_id')))->withTrashed()->first();
if ($invoice) {
$description = "Invoice {$invoice->number} for {$amount} for client {$this->square_driver->client->present()->name()}";
} else {
$description = "Payment with no invoice for amount {$amount} for client {$this->square_driver->client->present()->name()}";
}
$amount_money = new \Square\Models\Money();
$amount_money->setAmount($amount);
$amount_money->setCurrency($this->square_driver->client->currency()->code);
$body = new \Square\Models\CreatePaymentRequest($token, $request->idempotencyKey, $amount_money);
$body = new \Square\Models\CreatePaymentRequest($token, $request->idempotencyKey);
$body->setAmountMoney($amount_money);
$body->setAutocomplete(true);
$body->setLocationId($this->square_driver->company_gateway->getConfigField('locationId'));
$body->setReferenceId(Str::random(16));
$body->setReferenceId($this->square_driver->payment_hash->hash);
$body->setNote($description);
if ($request->shouldUseToken()) {
$body->setCustomerId($cgt->gateway_customer_reference);
}elseif ($request->has('verificationToken') && $request->input('verificationToken')) {
$body->setVerificationToken($request->input('verificationToken'));
}
/** @var ApiResponse */
$response = $this->square_driver->square->getPaymentsApi()->createPayment($body);
if ($response->isSuccess()) {

View File

@ -0,0 +1,280 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\PaymentDrivers\Square;
use App\Models\Payment;
use App\Models\SystemLog;
use App\Libraries\MultiDB;
use App\Models\GatewayType;
use App\Models\PaymentHash;
use App\Models\PaymentType;
use Illuminate\Bus\Queueable;
use App\Models\CompanyGateway;
use App\Jobs\Util\SystemLogger;
use App\Jobs\Mail\PaymentFailedMailer;
use Illuminate\Queue\SerializesModels;
use App\PaymentDrivers\Stripe\Utilities;
use Illuminate\Queue\InteractsWithQueue;
use App\PaymentDrivers\SquarePaymentDriver;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class SquareWebhook implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, Utilities;
public $tries = 1;
public $deleteWhenMissingModels = true;
public CompanyGateway $company_gateway;
public SquarePaymentDriver $driver;
public \Square\SquareClient $square;
private array $source_type = [
'CARD' => PaymentType::CREDIT_CARD_OTHER,
'BANK_ACCOUNT' => PaymentType::ACH,
'WALLET' => PaymentType::CREDIT_CARD_OTHER,
'BUY_NOW_PAY_LATER' => PaymentType::CREDIT_CARD_OTHER,
'SQUARE_ACCOUNT' => PaymentType::CREDIT_CARD_OTHER,
'CASH' => PaymentType::CASH,
'EXTERNAL' =>PaymentType::CREDIT_CARD_OTHER
];
public function __construct(public array $webhook_array, public string $company_key, public int $company_gateway_id)
{
}
/**
* {
* "merchant_id": "6SSW7HV8K2ST5",
* "type": "payment.created",
* "event_id": "13b867cf-db3d-4b1c-90b6-2f32a9d78124",
* "created_at": "2020-02-06T21:27:30.792Z",
* "data": {
* "type": "payment",
* "id": "KkAkhdMsgzn59SM8A89WgKwekxLZY",
* "object": {
* "payment": {
* "id": "hYy9pRFVxpDsO1FB05SunFWUe9JZY",
* "created_at": "2020-11-22T21:16:51.086Z",
* "updated_at": "2020-11-22T21:16:51.198Z",
* "amount_money": {
* "amount": 100,
* "currency": "USD"
* },
* "status": "APPROVED",
* "delay_duration": "PT168H",
* "source_type": "CARD",
* "card_details": {
* "status": "AUTHORIZED",
* "card": {
* "card_brand": "MASTERCARD",
* "last_4": "9029",
* "exp_month": 11,
* "exp_year": 2022,
* "fingerprint": "sq-1-Tvruf3vPQxlvI6n0IcKYfBukrcv6IqWr8UyBdViWXU2yzGn5VMJvrsHMKpINMhPmVg",
* "card_type": "CREDIT",
* "prepaid_type": "NOT_PREPAID",
* "bin": "540988"
* },
* "entry_method": "KEYED",
* "cvv_status": "CVV_ACCEPTED",
* "avs_status": "AVS_ACCEPTED",
* "statement_description": "SQ *DEFAULT TEST ACCOUNT",
* "card_payment_timeline": {
* "authorized_at": "2020-11-22T21:16:51.198Z"
*
*/
public function handle()
{
nlog("Square Webhook");
MultiDB::findAndSetDbByCompanyKey($this->company_key);
$this->company_gateway = CompanyGateway::query()->withTrashed()->find($this->company_gateway_id);
$this->driver = $this->company_gateway->driver()->init();
$this->square = $this->driver->square;
$status = $this->webhook_array['data']['object']['payment']['status'] ?? false;
$payment_id = $this->webhook_array['data']['object']['payment']['id'] ?? null;
$payment_status = false;
match($status){
'APPROVED' => $payment_status = false,
'COMPLETED' => $payment_status = Payment::STATUS_COMPLETED,
'PENDING' => $payment_status = Payment::STATUS_PENDING,
'CANCELED' => $payment_status = Payment::STATUS_CANCELLED,
'FAILED' => $payment_status = Payment::STATUS_FAILED,
default => $payment_status = false,
};
if(!$payment_status){
nlog("Square Webhook - Payment Status Not Found or not worthy of processing");
nlog($this->webhook_array);
}
$payment = $this->retrieveOrCreatePayment($payment_id, $payment_status);
/** If the status was pending and now is reporting as Failed / Cancelled - process failure path */
if($payment->status_id == Payment::STATUS_PENDING && in_array($payment_status, [Payment::STATUS_CANCELLED, Payment::STATUS_FAILED])){
$payment->service()->deletePayment();
if ($this->driver->payment_hash) {
$error = ctrans('texts.client_payment_failure_body', [
'invoice' => implode(',', $payment->invoices->pluck('number')->toArray()),
'amount' => array_sum(array_column($this->driver->payment_hash->invoices(), 'amount')) + $this->driver->payment_hash->fee_total,
]);
} else {
$error = 'Payment for '.$payment->client->present()->name()." for {$payment->amount} failed";
}
PaymentFailedMailer::dispatch(
$this->driver->payment_hash,
$this->driver->client->company,
$this->driver->client,
$error
);
}
elseif($payment->status_id == Payment::STATUS_PENDING && in_array($payment_status, [Payment::STATUS_COMPLETED, Payment::STATUS_COMPLETED])){
$payment->status_id = Payment::STATUS_COMPLETED;
$payment->save();
}
//toggle pending to completed.
}
private function retrieveOrCreatePayment(?string $payment_reference, int $payment_status): ?\App\Models\Payment
{
$payment = Payment::withTrashed()->where('transaction_reference', $payment_reference)->first();
if($payment)
return $payment;
/** Handles the edge case where for some reason the payment has not yet been recorded in Invoice Ninja */
$apiResponse = $this->square->getPaymentsApi()->getPayment($payment_reference);
// {
// "payment": {
// "id": "bP9mAsEMYPUGjjGNaNO5ZDVyLhSZY",
// "created_at": "2021-10-13T19:34:33.524Z",
// "updated_at": "2021-10-13T19:34:34.339Z",
// "amount_money": {
// "amount": 555,
// "currency": "USD"
// },
// "status": "COMPLETED",
// "delay_duration": "PT168H",
// "source_type": "CARD",
// "card_details": {
// "status": "CAPTURED",
// "card": {
// "card_brand": "VISA",
// "last_4": "1111",
// "exp_month": 11,
// "exp_year": 2022,
// "fingerprint": "sq-1-Hxim77tbdcbGejOejnoAklBVJed2YFLTmirfl8Q5XZzObTc8qY_U8RkwzoNL8dCEcQ",
// "card_type": "DEBIT",
// "prepaid_type": "NOT_PREPAID",
// "bin": "411111"
// },
// "entry_method": "KEYED",
// "cvv_status": "CVV_ACCEPTED",
// "avs_status": "AVS_ACCEPTED",
// "auth_result_code": "2Nkw7q",
// "statement_description": "SQ *EXAMPLE TEST GOSQ.C",
// "card_payment_timeline": {
// "authorized_at": "2021-10-13T19:34:33.680Z",
// "captured_at": "2021-10-13T19:34:34.340Z"
// }
// },
// "location_id": "L88917AVBK2S5",
// "order_id": "d7eKah653Z579f3gVtjlxpSlmUcZY",
// "processing_fee": [
// {
// "effective_at": "2021-10-13T21:34:35.000Z",
// "type": "INITIAL",
// "amount_money": {
// "amount": 34,
// "currency": "USD"
// }
// }
// ],
// "note": "Test Note",
// "total_money": {
// "amount": 555,
// "currency": "USD"
// },
// "approved_money": {
// "amount": 555,
// "currency": "USD"
// },
// "employee_id": "TMoK_ogh6rH1o4dV",
// "receipt_number": "bP9m",
// "receipt_url": "https://squareup.com/receipt/preview/bP9mAsEMYPUGjjGNaNO5ZDVyLhSZY",
// "delay_action": "CANCEL",
// "delayed_until": "2021-10-20T19:34:33.524Z",
// "team_member_id": "TMoK_ogh6rH1o4dV",
// "application_details": {
// "square_product": "VIRTUAL_TERMINAL",
// "application_id": "sq0ids-Pw67AZAlLVB7hsRmwlJPuA"
// },
// "version_token": "56pRkL3slrzet2iQrTp9n0bdJVYTB9YEWdTNjQfZOPV6o"
// }
// }
if($apiResponse->isSuccess()){
$payment_hash_id = $apiResponse->getPayment()->getReferenceId() ?? false;
$square_payment = $apiResponse->getPayment()->jsonSerialize();
$payment_hash = PaymentHash::where('hash', $payment_hash_id)->firstOrFail();
$payment_hash->data = array_merge((array) $payment_hash->data, (array)$square_payment);
$payment_hash->save();
$this->driver->setPaymentHash($payment_hash);
$this->driver->setClient($payment_hash->fee_invoice->client);
$data = [
'payment_type' => $this->source_type[$square_payment->source_type],
'amount' => $payment_hash->amount_with_fee,
'transaction_reference' => $square_payment->id,
'gateway_type_id' => GatewayType::BANK_TRANSFER,
];
$payment = $this->driver->createPayment($data, $payment_status);
SystemLogger::dispatch(
['response' => $this->webhook_array, 'data' => $square_payment],
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_SUCCESS,
SystemLog::TYPE_SQUARE,
$this->driver->client,
$this->driver->client->company,
);
return $payment;
}
else{
nlog("Square Webhook - Payment not found: $payment_reference");
nlog($apiResponse->getErrors());
return null;
}
}
}

View File

@ -11,18 +11,22 @@
namespace App\PaymentDrivers;
use App\Http\Requests\Payments\PaymentWebhookRequest;
use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken;
use App\Models\GatewayType;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\SystemLog;
use App\Models\GatewayType;
use App\Models\PaymentHash;
use App\Models\PaymentType;
use App\Models\SystemLog;
use App\PaymentDrivers\Square\CreditCard;
use App\Jobs\Util\SystemLogger;
use App\Utils\Traits\MakesHash;
use Square\Http\ApiResponse;
use Square\Utils\WebhooksHelper;
use App\Models\ClientGatewayToken;
use Square\Models\WebhookSubscription;
use App\PaymentDrivers\Square\CreditCard;
use App\PaymentDrivers\Square\SquareWebhook;
use Square\Models\CreateWebhookSubscriptionRequest;
use App\Http\Requests\Payments\PaymentWebhookRequest;
use Square\Models\Builders\RefundPaymentRequestBuilder;
class SquarePaymentDriver extends BaseDriver
{
@ -96,15 +100,115 @@ class SquarePaymentDriver extends BaseDriver
public function refund(Payment $payment, $amount, $return_client_response = false)
{
$this->init();
$this->client = $payment->client;
$amount_money = new \Square\Models\Money();
$amount_money->setAmount($this->convertAmount($amount));
$amount_money->setCurrency($this->client->currency()->code);
$body = new \Square\Models\RefundPaymentRequest(\Illuminate\Support\Str::random(32), $amount_money, $payment->transaction_reference);
$body = RefundPaymentRequestBuilder::init(\Illuminate\Support\Str::random(32), $amount_money)
->paymentId($payment->transaction_reference)
->reason('Refund Request')
->build();
$apiResponse = $this->square->getRefundsApi()->refundPayment($body);
if ($apiResponse->isSuccess()) {
$refundPaymentResponse = $apiResponse->getResult();
nlog($refundPaymentResponse);
/**
* - `PENDING` - Awaiting approval.
* - `COMPLETED` - Successfully completed.
* - `REJECTED` - The refund was rejected.
* - `FAILED` - An error occurred.
*/
$status = $refundPaymentResponse->getRefund()->getStatus();
if(in_array($status, ['COMPLETED', 'PENDING'])){
$transaction_reference = $refundPaymentResponse->getRefund()->getId();
$data = [
'transaction_reference' => $transaction_reference,
'transaction_response' => json_encode($refundPaymentResponse->getRefund()->jsonSerialize()),
'success' => true,
'description' => $refundPaymentResponse->getRefund()->getReason(),
'code' => $refundPaymentResponse->getRefund()->getReason(),
];
SystemLogger::dispatch(
[
'server_response' => $data,
'data' => request()->all()
],
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_SUCCESS,
SystemLog::TYPE_SQUARE,
$this->client,
$this->client->company
);
return $data;
}
elseif(in_array($status, ['REJECTED', 'FAILED'])) {
$transaction_reference = $refundPaymentResponse->getRefund()->getId();
$data = [
'transaction_reference' => $transaction_reference,
'transaction_response' => json_encode($refundPaymentResponse->getRefund()->jsonSerialize()),
'success' => false,
'description' => $refundPaymentResponse->getRefund()->getReason(),
'code' => $refundPaymentResponse->getRefund()->getReason(),
];
SystemLogger::dispatch(
[
'server_response' => $data,
'data' => request()->all()
],
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_FAILURE,
SystemLog::TYPE_SQUARE,
$this->client,
$this->client->company
);
return $data;
}
} else {
/** @var \Square\Models\Error $error */
$error = end($apiResponse->getErrors());
$data = [
'transaction_reference' => $payment->transaction_reference,
'transaction_response' => $error->jsonSerialize(),
'success' => false,
'description' => $error->getDetail(),
'code' => $error->getCode(),
];
SystemLogger::dispatch(
[
'server_response' => $data,
'data' => request()->all()
],
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_FAILURE,
SystemLog::TYPE_SQUARE,
$this->client,
$this->client->company
);
return $data;
}
/** @var ApiResponse */
$response = $this->square->getRefundsApi()->refund($body);
}
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
@ -126,10 +230,12 @@ class SquarePaymentDriver extends BaseDriver
$amount_money->setAmount($amount);
$amount_money->setCurrency($this->client->currency()->code);
$body = new \Square\Models\CreatePaymentRequest($cgt->token, \Illuminate\Support\Str::random(32), $amount_money);
$body = new \Square\Models\CreatePaymentRequest($cgt->token, \Illuminate\Support\Str::random(32));
$body->setCustomerId($cgt->gateway_customer_reference);
$body->setAmountMoney($amount_money);
$body->setReferenceId($payment_hash->hash);
$body->setNote(substr($description,0,500));
/** @var ApiResponse */
$response = $this->square->getPaymentsApi()->createPayment($body);
$body = json_decode($response->getBody());
@ -177,8 +283,107 @@ class SquarePaymentDriver extends BaseDriver
return false;
}
public function processWebhookRequest(PaymentWebhookRequest $request, Payment $payment = null)
public function checkWebhooks(): bool
{
$this->init();
$api_response = $this->square->getWebhookSubscriptionsApi()->listWebhookSubscriptions();
if ($api_response->isSuccess()) {
//array of WebhookSubscription objects
foreach($api_response->getResult()->getSubscriptions() as $subscription)
{
if($subscription->getName() == 'Invoice_Ninja_Webhook_Subscription')
return true;
}
} else {
$errors = $api_response->getErrors();
nlog($errors);
}
return false;
}
// {
// "subscription": {
// "id": "wbhk_b35f6b3145074cf9ad513610786c19d5",
// "name": "Example Webhook Subscription",
// "enabled": true,
// "event_types": [
// "payment.created",
// "order.updated",
// "invoice.created"
// ],
// "notification_url": "https://example-webhook-url.com",
// "api_version": "2021-12-15",
// "signature_key": "1k9bIJKCeTmSQwyagtNRLg",
// "created_at": "2022-08-17 23:29:48 +0000 UTC",
// "updated_at": "2022-08-17 23:29:48 +0000 UTC"
// }
// }
public function createWebhooks(): void
{
if($this->checkWebhooks())
return;
$this->init();
$event_types = ['payment.created', 'payment.updated'];
$subscription = new WebhookSubscription();
$subscription->setName('Invoice_Ninja_Webhook_Subscription');
$subscription->setEventTypes($event_types);
// $subscription->setNotificationUrl('https://invoicing.co');
$subscription->setNotificationUrl($this->company_gateway->webhookUrl());
// $subscription->setApiVersion('2021-12-15');
$body = new CreateWebhookSubscriptionRequest($subscription);
$body->setIdempotencyKey(\Illuminate\Support\Str::uuid());
$api_response = $this->square->getWebhookSubscriptionsApi()->createWebhookSubscription($body);
if ($api_response->isSuccess()) {
$subscription = $api_response->getResult()->getSubscription();
$signatureKey = $subscription->getSignatureKey();
$this->company_gateway->setConfigField('signatureKey', $signatureKey);
} else {
$errors = $api_response->getErrors();
nlog($errors);
}
}
public function processWebhookRequest(PaymentWebhookRequest $request)
{
$signature_key = $this->company_gateway->getConfigField('signatureKey');
$notification_url = $this->company_gateway->webhookUrl();
// header('Content-Type: text/plain');
// $webhook_payload = file_get_contents('php://input');
$body = '';
$handle = fopen('php://input', 'r');
while(!feof($handle)) {
$body .= fread($handle, 1024);
}
if (WebhooksHelper::isValidWebhookEventSignature($body, $request->header('x-square-hmacsha256-signature'), $signature_key, $notification_url)) {
SquareWebhook::dispatch($request->all(), $request->company_key, $this->company_gateway->id)->delay(5);
} else {
nlog("Square Hash Mismatch");
nlog($request->all());
}
return response()->json(['success' => true]);
}
public function convertAmount($amount)

View File

@ -86,7 +86,7 @@
"socialiteproviders/microsoft": "^4.1",
"spatie/laravel-data": "^3.5",
"sprain/swiss-qr-bill": "^3.2",
"square/square": "13.0.0.20210721",
"square/square": "30.0.0.*",
"stripe/stripe-php": "^7.50",
"symfony/http-client": "^6.0",
"symfony/mailgun-mailer": "^6.1",

265
composer.lock generated
View File

@ -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": "9d7348352c913eb82fcca2e67670e1f8",
"content-hash": "673ca66ddfdb05c3ea29012594a196d3",
"packages": [
{
"name": "adrienrn/php-mimetyper",
@ -99,21 +99,121 @@
"time": "2023-05-02T15:11:17+00:00"
},
{
"name": "apimatic/jsonmapper",
"version": "v2.0.3",
"name": "apimatic/core",
"version": "0.3.2",
"source": {
"type": "git",
"url": "https://github.com/apimatic/jsonmapper.git",
"reference": "f7588f1ab692c402a9118e65cb9fd42b74e5e0db"
"url": "https://github.com/apimatic/core-lib-php.git",
"reference": "32238fb83ce9a3ebef38c726b497c0f218d6e6c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/apimatic/jsonmapper/zipball/f7588f1ab692c402a9118e65cb9fd42b74e5e0db",
"reference": "f7588f1ab692c402a9118e65cb9fd42b74e5e0db",
"url": "https://api.github.com/repos/apimatic/core-lib-php/zipball/32238fb83ce9a3ebef38c726b497c0f218d6e6c9",
"reference": "32238fb83ce9a3ebef38c726b497c0f218d6e6c9",
"shasum": ""
},
"require": {
"apimatic/core-interfaces": "~0.1.0",
"apimatic/jsonmapper": "^3.1.1",
"ext-curl": "*",
"ext-dom": "*",
"ext-json": "*",
"ext-libxml": "*",
"php": "^7.2 || ^8.0",
"php-jsonpointer/php-jsonpointer": "^3.0.2"
},
"require-dev": {
"phpunit/phpunit": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
"phan/phan": "5.4.2",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"squizlabs/php_codesniffer": "^3.5"
},
"type": "library",
"autoload": {
"psr-4": {
"Core\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Core logic and the utilities for the Apimatic's PHP SDK",
"homepage": "https://github.com/apimatic/core-lib-php",
"keywords": [
"apimatic",
"core",
"corelib",
"php"
],
"support": {
"issues": "https://github.com/apimatic/core-lib-php/issues",
"source": "https://github.com/apimatic/core-lib-php/tree/0.3.2"
},
"time": "2023-07-11T09:30:32+00:00"
},
{
"name": "apimatic/core-interfaces",
"version": "0.1.2",
"source": {
"type": "git",
"url": "https://github.com/apimatic/core-interfaces-php.git",
"reference": "183214195a79784c382a446795c46ca8c1f43cc1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/apimatic/core-interfaces-php/zipball/183214195a79784c382a446795c46ca8c1f43cc1",
"reference": "183214195a79784c382a446795c46ca8c1f43cc1",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"type": "library",
"autoload": {
"psr-4": {
"CoreInterfaces\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Definition of the behavior of apimatic/core, apimatic/unirest-php and Apimatic's PHP SDK",
"homepage": "https://github.com/apimatic/core-interfaces-php",
"keywords": [
"apimatic",
"core",
"corelib",
"interface",
"php",
"unirest"
],
"support": {
"issues": "https://github.com/apimatic/core-interfaces-php/issues",
"source": "https://github.com/apimatic/core-interfaces-php/tree/0.1.2"
},
"time": "2023-04-04T06:40:52+00:00"
},
{
"name": "apimatic/jsonmapper",
"version": "3.1.2",
"source": {
"type": "git",
"url": "https://github.com/apimatic/jsonmapper.git",
"reference": "6673a946c21f2ceeec0cb60d17541c11a22bc79d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/apimatic/jsonmapper/zipball/6673a946c21f2ceeec0cb60d17541c11a22bc79d",
"reference": "6673a946c21f2ceeec0cb60d17541c11a22bc79d",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "^5.6 || ^7.0 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
"squizlabs/php_codesniffer": "^3.0.0"
},
"type": "library",
@ -144,37 +244,38 @@
"support": {
"email": "mehdi.jaffery@apimatic.io",
"issues": "https://github.com/apimatic/jsonmapper/issues",
"source": "https://github.com/apimatic/jsonmapper/tree/v2.0.3"
"source": "https://github.com/apimatic/jsonmapper/tree/3.1.2"
},
"time": "2021-07-16T09:02:23+00:00"
"time": "2023-06-08T04:27:10+00:00"
},
{
"name": "apimatic/unirest-php",
"version": "2.3.0",
"version": "4.0.5",
"source": {
"type": "git",
"url": "https://github.com/apimatic/unirest-php.git",
"reference": "52e226fb3b7081dc9ef64aee876142a240a5f0f9"
"reference": "e16754010c16be5473289470f129d87a0f41b55e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/apimatic/unirest-php/zipball/52e226fb3b7081dc9ef64aee876142a240a5f0f9",
"reference": "52e226fb3b7081dc9ef64aee876142a240a5f0f9",
"url": "https://api.github.com/repos/apimatic/unirest-php/zipball/e16754010c16be5473289470f129d87a0f41b55e",
"reference": "e16754010c16be5473289470f129d87a0f41b55e",
"shasum": ""
},
"require": {
"apimatic/core-interfaces": "^0.1.0",
"ext-curl": "*",
"php": ">=5.6.0"
"ext-json": "*",
"php": "^7.2 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^5 || ^6 || ^7 || ^8 || ^9"
},
"suggest": {
"ext-json": "Allows using JSON Bodies for sending and parsing requests"
"phan/phan": "5.4.2",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"squizlabs/php_codesniffer": "^3.5"
},
"type": "library",
"autoload": {
"psr-0": {
"psr-4": {
"Unirest\\": "src/"
}
},
@ -208,9 +309,9 @@
"support": {
"email": "opensource@apimatic.io",
"issues": "https://github.com/apimatic/unirest-php/issues",
"source": "https://github.com/apimatic/unirest-php/tree/2.3.0"
"source": "https://github.com/apimatic/unirest-php/tree/4.0.5"
},
"time": "2022-06-15T08:29:49+00:00"
"time": "2023-04-25T14:19:45+00:00"
},
{
"name": "asm/php-ansible",
@ -424,16 +525,16 @@
},
{
"name": "aws/aws-sdk-php",
"version": "3.279.0",
"version": "3.279.2",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
"reference": "7b3d38cfccd393add0ea0ce281de91846967c61e"
"reference": "ebd5e47c5be0425bb5cf4f80737850ed74767107"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7b3d38cfccd393add0ea0ce281de91846967c61e",
"reference": "7b3d38cfccd393add0ea0ce281de91846967c61e",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/ebd5e47c5be0425bb5cf4f80737850ed74767107",
"reference": "ebd5e47c5be0425bb5cf4f80737850ed74767107",
"shasum": ""
},
"require": {
@ -513,9 +614,9 @@
"support": {
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
"issues": "https://github.com/aws/aws-sdk-php/issues",
"source": "https://github.com/aws/aws-sdk-php/tree/3.279.0"
"source": "https://github.com/aws/aws-sdk-php/tree/3.279.2"
},
"time": "2023-08-16T18:18:34+00:00"
"time": "2023-08-18T18:13:09+00:00"
},
{
"name": "bacon/bacon-qr-code",
@ -1351,16 +1452,16 @@
},
{
"name": "doctrine/dbal",
"version": "3.6.5",
"version": "3.6.6",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "96d5a70fd91efdcec81fc46316efc5bf3da17ddf"
"reference": "63646ffd71d1676d2f747f871be31b7e921c7864"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/96d5a70fd91efdcec81fc46316efc5bf3da17ddf",
"reference": "96d5a70fd91efdcec81fc46316efc5bf3da17ddf",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/63646ffd71d1676d2f747f871be31b7e921c7864",
"reference": "63646ffd71d1676d2f747f871be31b7e921c7864",
"shasum": ""
},
"require": {
@ -1376,10 +1477,11 @@
"doctrine/coding-standard": "12.0.0",
"fig/log-test": "^1",
"jetbrains/phpstorm-stubs": "2023.1",
"phpstan/phpstan": "1.10.21",
"phpstan/phpstan": "1.10.29",
"phpstan/phpstan-strict-rules": "^1.5",
"phpunit/phpunit": "9.6.9",
"psalm/plugin-phpunit": "0.18.4",
"slevomat/coding-standard": "8.13.1",
"squizlabs/php_codesniffer": "3.7.2",
"symfony/cache": "^5.4|^6.0",
"symfony/console": "^4.4|^5.4|^6.0",
@ -1443,7 +1545,7 @@
],
"support": {
"issues": "https://github.com/doctrine/dbal/issues",
"source": "https://github.com/doctrine/dbal/tree/3.6.5"
"source": "https://github.com/doctrine/dbal/tree/3.6.6"
},
"funding": [
{
@ -1459,7 +1561,7 @@
"type": "tidelift"
}
],
"time": "2023-07-17T09:15:50+00:00"
"time": "2023-08-17T05:38:17+00:00"
},
{
"name": "doctrine/deprecations",
@ -3348,16 +3450,16 @@
},
{
"name": "horstoeko/zugferd",
"version": "v1.0.23",
"version": "v1.0.26",
"source": {
"type": "git",
"url": "https://github.com/horstoeko/zugferd.git",
"reference": "bb55417be4c4de8deb0113e832feeaf7b4d3984e"
"reference": "2a7541a35f00499c206391273f30159dc2c7072a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/horstoeko/zugferd/zipball/bb55417be4c4de8deb0113e832feeaf7b4d3984e",
"reference": "bb55417be4c4de8deb0113e832feeaf7b4d3984e",
"url": "https://api.github.com/repos/horstoeko/zugferd/zipball/2a7541a35f00499c206391273f30159dc2c7072a",
"reference": "2a7541a35f00499c206391273f30159dc2c7072a",
"shasum": ""
},
"require": {
@ -3415,9 +3517,9 @@
],
"support": {
"issues": "https://github.com/horstoeko/zugferd/issues",
"source": "https://github.com/horstoeko/zugferd/tree/v1.0.23"
"source": "https://github.com/horstoeko/zugferd/tree/v1.0.26"
},
"time": "2023-08-16T17:39:36+00:00"
"time": "2023-08-18T03:05:43+00:00"
},
{
"name": "http-interop/http-factory-guzzle",
@ -7664,6 +7766,62 @@
},
"time": "2020-07-07T09:29:14+00:00"
},
{
"name": "php-jsonpointer/php-jsonpointer",
"version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/raphaelstolt/php-jsonpointer.git",
"reference": "4428f86c6f23846e9faa5a420c4ef14e485b3afb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/raphaelstolt/php-jsonpointer/zipball/4428f86c6f23846e9faa5a420c4ef14e485b3afb",
"reference": "4428f86c6f23846e9faa5a420c4ef14e485b3afb",
"shasum": ""
},
"require": {
"php": ">=5.4"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^1.11",
"phpunit/phpunit": "4.6.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-0": {
"Rs\\Json": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Raphael Stolt",
"email": "raphael.stolt@gmail.com",
"homepage": "http://raphaelstolt.blogspot.com/"
}
],
"description": "Implementation of JSON Pointer (http://tools.ietf.org/html/rfc6901)",
"homepage": "https://github.com/raphaelstolt/php-jsonpointer",
"keywords": [
"json",
"json pointer",
"json traversal"
],
"support": {
"issues": "https://github.com/raphaelstolt/php-jsonpointer/issues",
"source": "https://github.com/raphaelstolt/php-jsonpointer/tree/master"
},
"time": "2016-08-29T08:51:01+00:00"
},
{
"name": "phpdocumentor/reflection-common",
"version": "2.2.0",
@ -10037,29 +10195,28 @@
},
{
"name": "square/square",
"version": "13.0.0.20210721",
"version": "30.0.0.20230816",
"source": {
"type": "git",
"url": "https://github.com/square/square-php-sdk.git",
"reference": "03d90445854cd3b500f75061a9c63956799b8ecf"
"reference": "fedfea8b6c6f16b6a90ef0d629743ae9ae25e13d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/square/square-php-sdk/zipball/03d90445854cd3b500f75061a9c63956799b8ecf",
"reference": "03d90445854cd3b500f75061a9c63956799b8ecf",
"url": "https://api.github.com/repos/square/square-php-sdk/zipball/fedfea8b6c6f16b6a90ef0d629743ae9ae25e13d",
"reference": "fedfea8b6c6f16b6a90ef0d629743ae9ae25e13d",
"shasum": ""
},
"require": {
"apimatic/jsonmapper": "^2.0.2",
"apimatic/unirest-php": "^2.0",
"ext-curl": "*",
"apimatic/core": "~0.3.0",
"apimatic/core-interfaces": "~0.1.0",
"apimatic/unirest-php": "^4.0.0",
"ext-json": "*",
"ext-mbstring": "*",
"php": ">=7.2"
"php": "^7.2 || ^8.0"
},
"require-dev": {
"phan/phan": "^3.0",
"phpunit/phpunit": "^7.5 || ^8.5",
"phan/phan": "5.4.2",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"squizlabs/php_codesniffer": "^3.5"
},
"type": "library",
@ -10088,9 +10245,9 @@
],
"support": {
"issues": "https://github.com/square/square-php-sdk/issues",
"source": "https://github.com/square/square-php-sdk/tree/13.0.0.20210721"
"source": "https://github.com/square/square-php-sdk/tree/30.0.0.20230816"
},
"time": "2021-07-21T06:43:15+00:00"
"time": "2023-08-15T21:45:55+00:00"
},
{
"name": "stripe/stripe-php",

View File

@ -80,7 +80,7 @@ class PaymentLibrariesSeeder extends Seeder
['id' => 53, 'name' => 'PagSeguro', 'provider' => 'PagSeguro', 'key' => 'ef498756b54db63c143af0ec433da803', 'fields' => '{"email":"","token":"","sandbox":false}'],
['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' => 57, 'name' => 'Square', 'provider' => 'Square', 'is_offsite' => false, 'sort_order' => 21, 'key' => '65faab2ab6e3223dbe848b1686490baz', 'fields' => '{"accessToken":"","applicationId":"","locationId":"","signatureKey":"","testMode":false}'],
['id' => 58, 'name' => 'Razorpay', 'provider' => 'Razorpay', 'is_offsite' => false, 'sort_order' => 21, 'key' => 'hxd6gwg3ekb9tb3v9lptgx1mqyg69zu9', 'fields' => '{"apiKey":"","apiSecret":""}'],
['id' => 59, 'name' => 'Forte', 'provider' => 'Forte', 'is_offsite' => false, 'sort_order' => 21, 'key' => 'kivcvjexxvdiyqtj3mju5d6yhpeht2xs', 'fields' => '{"testMode":false,"apiLoginId":"","apiAccessId":"","secureKey":"","authOrganizationId":"","organizationId":"","locationId":""}'],
['id' => 60, 'name' => 'PayPal REST', 'provider' => 'PayPal_Rest', 'key' => '80af24a6a691230bbec33e930ab40665', 'fields' => '{"clientId":"","secret":"","signature":"","testMode":false}'],

View File

@ -47,6 +47,22 @@ class CompanyGatewayTest extends TestCase
$this->assertNotNull($company_gateway);
}
public function testSetConfigFields()
{
$company_gateway = CompanyGateway::first();
$this->assertNotNull($company_gateway->getConfig());
$company_gateway->setConfigField('test', 'test');
$this->assertEquals('test', $company_gateway->getConfigField('test'));
$company_gateway->setConfigField('signatureKey', 'hero');
$this->assertEquals('hero', $company_gateway->getConfigField('signatureKey'));
}
public function testFeesAndLimitsExists()
{
$data = [];