Skip to content

Commit

Permalink
feature: add initial classes for an off-site gateway sample
Browse files Browse the repository at this point in the history
  • Loading branch information
glaubersilva committed May 24, 2024
1 parent 1f44c14 commit e8f9f03
Show file tree
Hide file tree
Showing 5 changed files with 315 additions and 0 deletions.
2 changes: 2 additions & 0 deletions give-addon-boilerplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use GiveAddon\Addon\Environment;
use GiveAddon\Domain\AddonServiceProvider;
use GiveAddon\FormExtension\FormExtensionServiceProvider;
use GiveAddon\OffSiteGateway\OffSiteGatewayServiceProvider;

/**
* Plugin Name: ADDON_NAME
Expand Down Expand Up @@ -52,6 +53,7 @@ function () {
if (Environment::giveMinRequiredVersionCheck()) {
give()->registerServiceProvider(AddonServiceProvider::class);
give()->registerServiceProvider(FormExtensionServiceProvider::class);
give()->registerServiceProvider(OffSiteGatewayServiceProvider::class);
}
}
);
Expand Down
27 changes: 27 additions & 0 deletions src/OffSiteGateway/DataTransferObjects/OffSiteGatewayPayment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace GiveAddon\OffSiteGateway\DataTransferObjects;

class OffSiteGatewayPayment
{

/**
* @var string
*/
public $id;

/**
* @var string
*/
public $checkoutUrl;

public static function fromArray(array $data): OffSiteGatewayPayment
{
$self = new self();

$self->id = $data['id'] ?? '';
$self->checkoutUrl = $data['checkoutUrl'] ?? '';

return $self;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace GiveAddon\OffSiteGateway\DataTransferObjects;

/**
* @unreleased
*/
class OffSiteGatewayWebhookNotification
{
/**
* @var string
*/
public $notificationType;

public static function fromArray(array $data): OffSiteGatewayWebhookNotification
{
$self = new self();

$self->notificationType = $data['notification_type'] ?? '';

return $self;
}
}
226 changes: 226 additions & 0 deletions src/OffSiteGateway/Gateway/OffSiteGateway.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
<?php

namespace GiveAddon\OffSiteGateway\Gateway;

use Exception;
use Give\Donations\Models\Donation;
use Give\Donations\Models\DonationNote;
use Give\Donations\ValueObjects\DonationStatus;
use Give\Framework\Http\Response\Types\RedirectResponse;
use Give\Framework\PaymentGateways\Commands\RedirectOffsite;
use Give\Framework\PaymentGateways\Exceptions\PaymentGatewayException;
use Give\Framework\PaymentGateways\PaymentGateway;
use GiveAddon\OffSiteGateway\DataTransferObjects\OffSiteGatewayPayment;

/**
* @unreleased
*/
class OffSiteGateway extends PaymentGateway
{
/**
* @unreleased
*/
public $secureRouteMethods = [
'handleSuccessPaymentReturn',
'handleCanceledPaymentReturn',
];

/**
* @unreleased
*/
public $routeMethods = [
'webhookNotificationsListener',
];

/**
* @unreleased
*/
public function getWebhookNotificationsListener(): string
{
return $this->routeMethods[0];
}

/**
* @unreleased
*/
public static function id(): string
{
return 'ADDON_ID-off-site-gateway';
}

/**
* @unreleased
*/
public function getId(): string
{
return self::id();
}

/**
* @unreleased
*/
public function getName(): string
{
return __('ADDON_NAME - Off-Site Gateway', 'ADDON_TEXTDOMAIN');
}

/**
* @unreleased
*/
public function getPaymentMethodLabel(): string
{
return __('ADDON_NAME - Off-Site Gateway', 'ADDON_TEXTDOMAIN');
}

/**
* @unreleased
*/
public function getLegacyFormFieldMarkup(int $formId, array $args): string
{
return '<p>The Off-Site Gateway Logo Goes Here...</p>';
}

/**
* @unreleased
*
* @throws Exception
*/
public function createPayment(Donation $donation, $gatewayData): RedirectOffsite
{
try {
$paymentParameters = $this->getPaymentParameters($donation, $gatewayData);
$payment = $this->createGiveAddonOffSiteGatewayPayment($donation, $paymentParameters);
$donation->gatewayTransactionId = $payment->id;
$donation->save();

return new RedirectOffsite($payment->checkoutUrl);
} catch (Exception $e) {
$donation->status = DonationStatus::FAILED();
$donation->save();

$errorMessage = $e->getMessage();

DonationNote::create([
'donationId' => $donation->id,
'content' => sprintf(esc_html__('Donation failed. Reason: %s', 'ADDON_TEXTDOMAIN'), $errorMessage),
]);

throw new PaymentGatewayException($errorMessage);
}
}

/**
* @unreleased
*/
public function refundDonation(Donation $donation)
{
// TODO: Implement refundDonation() method.
}

/**
* @unreleased
*/
public function getPaymentParameters(Donation $donation, $gatewayData): array
{
return [
'amount' => [
'value' => $donation->amount->formatToDecimal(),
'currency' => $donation->amount->getCurrency()->getCode(),
],
//'description' => MollieApi::getPaymentDescription($donation),
'returnUrl' => $this->getPaymentsReturnURL($donation, $gatewayData),
'cancelUrl' => $this->getPaymentsCancelURL($donation, $gatewayData),
'webhookUrl' => $this->getPaymentsWebhookUrl($donation),
];
}

/**
* @param Donation $donation
* @param array $paymentParameters
*
* @return OffSiteGatewayPayment
*/
protected function createGiveAddonOffSiteGatewayPayment(
Donation $donation,
array $paymentParameters
): OffSiteGatewayPayment {
return OffSiteGatewayPayment::fromArray([
'id' => 'payment-id',
'checkoutUrl' => 'https://example.com/',
]);
}

/**
* @unreleased
*
* @throws Exception
*/
protected function handleSuccessPaymentReturn(array $queryParams): RedirectResponse
{
$donation = Donation::find((int)$queryParams['donation-id']);

$donation->status = DonationStatus::COMPLETE();
$donation->save();

return new RedirectResponse(esc_url_raw($queryParams['givewp-return-url']));
}

/**
* @unreleased
*
* @throws Exception
*/
protected function handleCanceledPaymentReturn(array $queryParams): RedirectResponse
{
$donation = Donation::find((int)$queryParams['donation-id']);

$donation->status = DonationStatus::CANCELLED();
$donation->save();

return new RedirectResponse(esc_url_raw($queryParams['givewp-return-url']));
}

/**
* @unreleased
*/
private function getPaymentsReturnURL(Donation $donation, $gatewayData): string
{
return $this->generateSecureGatewayRouteUrl(
'handleSuccessPaymentReturn',
$donation->id,
[
'donation-id' => $donation->id,
'givewp-return-url' => $gatewayData['successUrl'],
]
);
}

/**
* @unreleased
*/
private function getPaymentsCancelURL(Donation $donation, $gatewayData): string
{
return $this->generateSecureGatewayRouteUrl(
'handleCanceledPaymentReturn',
$donation->id,
[
'donation-id' => $donation->id,
'givewp-return-url' => $gatewayData['cancelUrl'],
]
);
}

/**
* @unreleased
*/
private function getPaymentsWebhookUrl(Donation $donation): string
{
return $this->generateGatewayRouteUrl(
$this->getWebhookNotificationsListener(),
[
'notification_type' => 'payments',
'payment_id' => $donation->id,
]
);
}
}
37 changes: 37 additions & 0 deletions src/OffSiteGateway/OffSiteGatewayServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace GiveAddon\OffSiteGateway;

use Exception;
use Give\Framework\PaymentGateways\PaymentGatewayRegister;
use Give\ServiceProviders\ServiceProvider;
use GiveAddon\OffSiteGateway\Gateway\OffSiteGateway;

/**
* @unreleased
*/
class OffSiteGatewayServiceProvider implements ServiceProvider
{
/**
* @unreleased
*/
public function register()
{
// TODO: Implement register() method.
}

/**
* @unreleased
*
* @throws Exception
*/
public function boot()
{
add_action(
'givewp_register_payment_gateway',
function (PaymentGatewayRegister $registrar) {
$registrar->registerGateway(OffSiteGateway::class);
}
);
}
}

0 comments on commit e8f9f03

Please sign in to comment.