From e8f9f039502734c7e5f9efa6c338f89e9d76f2fc Mon Sep 17 00:00:00 2001 From: Glauber Silva Date: Fri, 24 May 2024 15:51:21 -0300 Subject: [PATCH] feature: add initial classes for an off-site gateway sample --- give-addon-boilerplate.php | 2 + .../OffSiteGatewayPayment.php | 27 +++ .../OffSiteGatewayWebhookNotification.php | 23 ++ src/OffSiteGateway/Gateway/OffSiteGateway.php | 226 ++++++++++++++++++ .../OffSiteGatewayServiceProvider.php | 37 +++ 5 files changed, 315 insertions(+) create mode 100644 src/OffSiteGateway/DataTransferObjects/OffSiteGatewayPayment.php create mode 100644 src/OffSiteGateway/DataTransferObjects/OffSiteGatewayWebhookNotification.php create mode 100644 src/OffSiteGateway/Gateway/OffSiteGateway.php create mode 100644 src/OffSiteGateway/OffSiteGatewayServiceProvider.php diff --git a/give-addon-boilerplate.php b/give-addon-boilerplate.php index 706d56f..7a7a5cd 100644 --- a/give-addon-boilerplate.php +++ b/give-addon-boilerplate.php @@ -5,6 +5,7 @@ use GiveAddon\Addon\Environment; use GiveAddon\Domain\AddonServiceProvider; use GiveAddon\FormExtension\FormExtensionServiceProvider; +use GiveAddon\OffSiteGateway\OffSiteGatewayServiceProvider; /** * Plugin Name: ADDON_NAME @@ -52,6 +53,7 @@ function () { if (Environment::giveMinRequiredVersionCheck()) { give()->registerServiceProvider(AddonServiceProvider::class); give()->registerServiceProvider(FormExtensionServiceProvider::class); + give()->registerServiceProvider(OffSiteGatewayServiceProvider::class); } } ); diff --git a/src/OffSiteGateway/DataTransferObjects/OffSiteGatewayPayment.php b/src/OffSiteGateway/DataTransferObjects/OffSiteGatewayPayment.php new file mode 100644 index 0000000..bad0d7c --- /dev/null +++ b/src/OffSiteGateway/DataTransferObjects/OffSiteGatewayPayment.php @@ -0,0 +1,27 @@ +id = $data['id'] ?? ''; + $self->checkoutUrl = $data['checkoutUrl'] ?? ''; + + return $self; + } +} diff --git a/src/OffSiteGateway/DataTransferObjects/OffSiteGatewayWebhookNotification.php b/src/OffSiteGateway/DataTransferObjects/OffSiteGatewayWebhookNotification.php new file mode 100644 index 0000000..08ecf42 --- /dev/null +++ b/src/OffSiteGateway/DataTransferObjects/OffSiteGatewayWebhookNotification.php @@ -0,0 +1,23 @@ +notificationType = $data['notification_type'] ?? ''; + + return $self; + } +} diff --git a/src/OffSiteGateway/Gateway/OffSiteGateway.php b/src/OffSiteGateway/Gateway/OffSiteGateway.php new file mode 100644 index 0000000..87e4efe --- /dev/null +++ b/src/OffSiteGateway/Gateway/OffSiteGateway.php @@ -0,0 +1,226 @@ +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 '

The Off-Site Gateway Logo Goes Here...

'; + } + + /** + * @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, + ] + ); + } +} diff --git a/src/OffSiteGateway/OffSiteGatewayServiceProvider.php b/src/OffSiteGateway/OffSiteGatewayServiceProvider.php new file mode 100644 index 0000000..fbacce1 --- /dev/null +++ b/src/OffSiteGateway/OffSiteGatewayServiceProvider.php @@ -0,0 +1,37 @@ +registerGateway(OffSiteGateway::class); + } + ); + } +}