Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(connector): generate connector template code for gpayments authenticaition connector #4584

Merged
merged 8 commits into from
May 13, 2024
2 changes: 2 additions & 0 deletions config/config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ forte.base_url = "https://sandbox.forte.net/api/v3"
globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/"
globepay.base_url = "https://pay.globepay.co/"
gocardless.base_url = "https://api-sandbox.gocardless.com"
gpayments.base_url = "https://{{merchant_endpoint_prefix}}-test.api.as1.gpayments.net"
helcim.base_url = "https://api.helcim.com/"
iatapay.base_url = "https://sandbox.iata-pay.iata.org/api/v1"
klarna.base_url = "https://api-na.playground.klarna.com/"
Expand Down Expand Up @@ -275,6 +276,7 @@ cards = [
"globalpay",
"globepay",
"gocardless",
"gpayments",
"helcim",
"mollie",
"paypal",
Expand Down
2 changes: 2 additions & 0 deletions config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
"globalpay",
"globepay",
"gocardless",
"gpayments",
"helcim",
"iatapay",
"mollie",
Expand Down Expand Up @@ -192,6 +193,7 @@
globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/"
globepay.base_url = "https://pay.globepay.co/"
gocardless.base_url = "https://api-sandbox.gocardless.com"
gpayments.base_url = "https://{{merchant_endpoint_prefix}}-test.api.as1.gpayments.net"
helcim.base_url = "https://api.helcim.com/"
iatapay.base_url = "https://sandbox.iata-pay.iata.org/api/v1"
klarna.base_url = "https://api-na.playground.klarna.com/"
Expand Down Expand Up @@ -325,7 +327,7 @@
open_banking_uk = { country = "DE,GB,AT,BE,CY,EE,ES,FI,FR,GR,HR,IE,IT,LT,LU,LV,MT,NL,PT,SI,SK,BG,CZ,DK,HU,NO,PL,RO,SE,AU,BR", currency = "EUR,GBP,DKK,NOK,PLN,SEK,AUD,BRL" }

[pm_filters.adyen]
google_pay = { country = "AU,NZ,JP,HK,SG,MY,TH,VN,BH,AE,KW,BR,ES,GB,SE,NO,SK,AT,NL,DE,HU,CY,LU,CH,BE,FR,DK,RO,HR,LI,MT,SI,GR,PT,IE,CZ,EE,LT,LV,IT,PL,TR,IS,CA,US", currency = "AED,ALL,AMD,ANG,AOA,ARS,AUD,AWG,AZN,BAM,BBD,BDT,BGN,BHD,BMD,BND,BOB,BRL,BSD,BWP,BYN,BZD,CAD,CHF,CLP,CNY,COP,CRC,CUP,CVE,CZK,DJF,DKK,DOP,DZD,EGP,ETB,EUR,FJD,FKP,GBP,GEL,GHS,GIP,GMD,GNF,GTQ,GYD,HKD,HNL,HTG,HUF,IDR,ILS,INR,IQD,JMD,JOD,JPY,KES,KGS,KHR,KMF,KRW,KWD,KYD,KZT,LAK,LBP,LKR,LYD,MAD,MDL,MKD,MMK,MNT,MOP,MRU,MUR,MVR,MWK,MXN,MYR,MZN,NAD,NGN,NIO,NOK,NPR,NZD,OMR,PAB,PEN,PGK,PHP,PKR,PLN,PYG,QAR,RON,RSD,RUB,RWF,SAR,SBD,SCR,SEK,SGD,SHP,SLE,SOS,SRD,STN,SVC,SZL,THB,TND,TOP,TRY,TTD,TWD,TZS,UAH,UGX,USD,UYU,UZS,VES,VND,VUV,WST,XAF,XCD,XOF,XPF,YER,ZAR,ZMW" }

Check warning on line 330 in config/development.toml

View workflow job for this annotation

GitHub Actions / Spell check

"JOD" should be "JOB".
apple_pay = { country = "AU,NZ,CN,JP,HK,SG,MY,BH,AE,KW,BR,ES,GB,SE,NO,AT,NL,DE,HU,CY,LU,CH,BE,FR,DK,FI,RO,HR,LI,UA,MT,SI,GR,PT,IE,CZ,EE,LT,LV,IT,PL,IS,CA,US", currency = "AUD,CHF,CAD,EUR,GBP,HKD,SGD,USD" }
paypal = { country = "AU,NZ,CN,JP,HK,MY,TH,KR,PH,ID,AE,KW,BR,ES,GB,SE,NO,SK,AT,NL,DE,HU,CY,LU,CH,BE,FR,DK,FI,RO,HR,UA,MT,SI,GI,PT,IE,CZ,EE,LT,LV,IT,PL,IS,CA,US", currency = "AUD,BRL,CAD,CZK,DKK,EUR,HKD,HUF,INR,JPY,MYR,MXN,NZD,NOK,PHP,PLN,RUB,GBP,SGD,SEK,CHF,THB,USD" }
mobile_pay = { country = "DK,FI", currency = "DKK,SEK,NOK,EUR" }
Expand Down
2 changes: 2 additions & 0 deletions config/docker_compose.toml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ forte.base_url = "https://sandbox.forte.net/api/v3"
globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/"
globepay.base_url = "https://pay.globepay.co/"
gocardless.base_url = "https://api-sandbox.gocardless.com"
gpayments.base_url = "https://{{merchant_endpoint_prefix}}-test.api.as1.gpayments.net"
helcim.base_url = "https://api.helcim.com/"
iatapay.base_url = "https://sandbox.iata-pay.iata.org/api/v1"
klarna.base_url = "https://api-na.playground.klarna.com/"
Expand Down Expand Up @@ -204,6 +205,7 @@ cards = [
"globalpay",
"globepay",
"gocardless",
"gpayments",
"helcim",
"iatapay",
"mollie",
Expand Down
3 changes: 3 additions & 0 deletions crates/api_models/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ pub enum Connector {
Globalpay,
Globepay,
Gocardless,
// Gpayments, Added as template code for future usage
Helcim,
Iatapay,
Klarna,
Expand Down Expand Up @@ -209,6 +210,7 @@ impl Connector {
| Self::Globalpay
| Self::Globepay
| Self::Gocardless
// | Self::Gpayments Added as template code for future usage
| Self::Helcim
| Self::Iatapay
| Self::Klarna
Expand Down Expand Up @@ -268,6 +270,7 @@ impl Connector {
pub enum AuthenticationConnectors {
Threedsecureio,
Netcetera,
Gpayments,
}

#[cfg(feature = "payouts")]
Expand Down
3 changes: 3 additions & 0 deletions crates/connector_configs/src/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ pub struct ConnectorConfig {
pub globalpay: Option<ConnectorTomlConfig>,
pub globepay: Option<ConnectorTomlConfig>,
pub gocardless: Option<ConnectorTomlConfig>,
pub gpayments: Option<ConnectorTomlConfig>,
pub helcim: Option<ConnectorTomlConfig>,
pub klarna: Option<ConnectorTomlConfig>,
pub mollie: Option<ConnectorTomlConfig>,
Expand Down Expand Up @@ -236,6 +237,7 @@ impl ConnectorConfig {
match connector {
AuthenticationConnectors::Threedsecureio => Ok(connector_data.threedsecureio),
AuthenticationConnectors::Netcetera => Ok(connector_data.netcetera),
AuthenticationConnectors::Gpayments => Ok(connector_data.gpayments),
}
}

Expand Down Expand Up @@ -269,6 +271,7 @@ impl ConnectorConfig {
Connector::Globalpay => Ok(connector_data.globalpay),
Connector::Globepay => Ok(connector_data.globepay),
Connector::Gocardless => Ok(connector_data.gocardless),
// Connector::Gpayments => Ok(connector_data.gpayments), Added as template code for future usage
Connector::Helcim => Ok(connector_data.helcim),
Connector::Klarna => Ok(connector_data.klarna),
Connector::Mollie => Ok(connector_data.mollie),
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/configs/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ pub struct Connectors {
pub globalpay: ConnectorParams,
pub globepay: ConnectorParams,
pub gocardless: ConnectorParams,
pub gpayments: ConnectorParams,
pub helcim: ConnectorParams,
pub iatapay: ConnectorParams,
pub klarna: ConnectorParams,
Expand Down
18 changes: 10 additions & 8 deletions crates/router/src/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub mod forte;
pub mod globalpay;
pub mod globepay;
pub mod gocardless;
pub mod gpayments;
pub mod helcim;
pub mod iatapay;
pub mod klarna;
Expand Down Expand Up @@ -70,12 +71,13 @@ pub use self::{
bluesnap::Bluesnap, boku::Boku, braintree::Braintree, cashtocode::Cashtocode,
checkout::Checkout, coinbase::Coinbase, cryptopay::Cryptopay, cybersource::Cybersource,
dlocal::Dlocal, ebanx::Ebanx, fiserv::Fiserv, forte::Forte, globalpay::Globalpay,
globepay::Globepay, gocardless::Gocardless, helcim::Helcim, iatapay::Iatapay, klarna::Klarna,
mifinity::Mifinity, mollie::Mollie, multisafepay::Multisafepay, netcetera::Netcetera,
nexinets::Nexinets, nmi::Nmi, noon::Noon, nuvei::Nuvei, opayo::Opayo, opennode::Opennode,
payeezy::Payeezy, payme::Payme, payone::Payone, paypal::Paypal, payu::Payu,
placetopay::Placetopay, powertranz::Powertranz, prophetpay::Prophetpay, rapyd::Rapyd,
riskified::Riskified, shift4::Shift4, signifyd::Signifyd, square::Square, stax::Stax,
stripe::Stripe, threedsecureio::Threedsecureio, trustpay::Trustpay, tsys::Tsys, volt::Volt,
wise::Wise, worldline::Worldline, worldpay::Worldpay, zen::Zen, zsl::Zsl,
globepay::Globepay, gocardless::Gocardless, gpayments::Gpayments, helcim::Helcim,
iatapay::Iatapay, klarna::Klarna, mifinity::Mifinity, mollie::Mollie,
multisafepay::Multisafepay, netcetera::Netcetera, nexinets::Nexinets, nmi::Nmi, noon::Noon,
nuvei::Nuvei, opayo::Opayo, opennode::Opennode, payeezy::Payeezy, payme::Payme, payone::Payone,
paypal::Paypal, payu::Payu, placetopay::Placetopay, powertranz::Powertranz,
prophetpay::Prophetpay, rapyd::Rapyd, riskified::Riskified, shift4::Shift4, signifyd::Signifyd,
square::Square, stax::Stax, stripe::Stripe, threedsecureio::Threedsecureio, trustpay::Trustpay,
tsys::Tsys, volt::Volt, wise::Wise, worldline::Worldline, worldpay::Worldpay, zen::Zen,
zsl::Zsl,
};
231 changes: 231 additions & 0 deletions crates/router/src/connector/gpayments.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
pub mod transformers;

use std::fmt::Debug;

use error_stack::{report, ResultExt};
use masking::ExposeInterface;
use transformers as gpayments;

use crate::{
configs::settings,
core::errors::{self, CustomResult},
events::connector_api_logs::ConnectorEvent,
headers,
services::{
request::{self, Mask},
ConnectorIntegration, ConnectorValidation,
},
types::{
self,
api::{self, ConnectorCommon, ConnectorCommonExt},
ErrorResponse, Response,
},
utils::BytesExt,
};

#[derive(Debug, Clone)]
pub struct Gpayments;

impl api::Payment for Gpayments {}
impl api::PaymentSession for Gpayments {}
impl api::ConnectorAccessToken for Gpayments {}
impl api::MandateSetup for Gpayments {}
impl api::PaymentAuthorize for Gpayments {}
impl api::PaymentSync for Gpayments {}
impl api::PaymentCapture for Gpayments {}
impl api::PaymentVoid for Gpayments {}
impl api::Refund for Gpayments {}
impl api::RefundExecute for Gpayments {}
impl api::RefundSync for Gpayments {}
impl api::PaymentToken for Gpayments {}

impl
ConnectorIntegration<
api::PaymentMethodToken,
types::PaymentMethodTokenizationData,
types::PaymentsResponseData,
> for Gpayments
{
// Not Implemented (R)
}

impl<Flow, Request, Response> ConnectorCommonExt<Flow, Request, Response> for Gpayments
where
Self: ConnectorIntegration<Flow, Request, Response>,
{
fn build_headers(
&self,
req: &types::RouterData<Flow, Request, Response>,
_connectors: &settings::Connectors,
) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> {
let mut header = vec![(
headers::CONTENT_TYPE.to_string(),
self.get_content_type().to_string().into(),
)];
let mut api_key = self.get_auth_header(&req.connector_auth_type)?;
header.append(&mut api_key);
Ok(header)
}
}

impl ConnectorCommon for Gpayments {
fn id(&self) -> &'static str {
"gpayments"
}

fn get_currency_unit(&self) -> api::CurrencyUnit {
api::CurrencyUnit::Minor
// TODO! Check connector documentation, on which unit they are processing the currency.
// If the connector accepts amount in lower unit ( i.e cents for USD) then return api::CurrencyUnit::Minor,
// if connector accepts amount in base unit (i.e dollars for USD) then return api::CurrencyUnit::Base
}

fn common_get_content_type(&self) -> &'static str {
"application/json"
}

fn base_url<'a>(&self, connectors: &'a settings::Connectors) -> &'a str {
connectors.gpayments.base_url.as_ref()
}

fn get_auth_header(
&self,
auth_type: &types::ConnectorAuthType,
) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> {
let auth = gpayments::GpaymentsAuthType::try_from(auth_type)
.change_context(errors::ConnectorError::FailedToObtainAuthType)?;
Ok(vec![(
headers::AUTHORIZATION.to_string(),
auth.api_key.expose().into_masked(),
)])
}

fn build_error_response(
&self,
res: Response,
event_builder: Option<&mut ConnectorEvent>,
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
let response: gpayments::GpaymentsErrorResponse = res
.response
.parse_struct("GpaymentsErrorResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);

Ok(ErrorResponse {
status_code: res.status_code,
code: response.code,
message: response.message,
reason: response.reason,
attempt_status: None,
connector_transaction_id: None,
})
}
}

impl ConnectorValidation for Gpayments {
//TODO: implement functions when support enabled
}

impl ConnectorIntegration<api::Session, types::PaymentsSessionData, types::PaymentsResponseData>
for Gpayments
{
}

impl ConnectorIntegration<api::AccessTokenAuth, types::AccessTokenRequestData, types::AccessToken>
for Gpayments
{
}

impl
ConnectorIntegration<
api::SetupMandate,
types::SetupMandateRequestData,
types::PaymentsResponseData,
> for Gpayments
{
}

impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::PaymentsResponseData>
for Gpayments
{
}

impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsResponseData>
for Gpayments
{
}

impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::PaymentsResponseData>
for Gpayments
{
}

impl ConnectorIntegration<api::Void, types::PaymentsCancelData, types::PaymentsResponseData>
for Gpayments
{
}

impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsResponseData>
for Gpayments
{
}

impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponseData>
for Gpayments
{
}

#[async_trait::async_trait]
impl api::IncomingWebhook for Gpayments {
fn get_webhook_object_reference_id(
&self,
_request: &api::IncomingWebhookRequestDetails<'_>,
) -> CustomResult<api::webhooks::ObjectReferenceId, errors::ConnectorError> {
Err(report!(errors::ConnectorError::WebhooksNotImplemented))
}

fn get_webhook_event_type(
&self,
_request: &api::IncomingWebhookRequestDetails<'_>,
) -> CustomResult<api::IncomingWebhookEvent, errors::ConnectorError> {
Err(report!(errors::ConnectorError::WebhooksNotImplemented))
}

fn get_webhook_resource_object(
&self,
_request: &api::IncomingWebhookRequestDetails<'_>,
) -> CustomResult<Box<dyn masking::ErasedMaskSerialize>, errors::ConnectorError> {
Err(report!(errors::ConnectorError::WebhooksNotImplemented))
}
}

impl api::ExternalAuthentication for Gpayments {}
impl api::ConnectorAuthentication for Gpayments {}
impl api::ConnectorPreAuthentication for Gpayments {}
impl api::ConnectorPostAuthentication for Gpayments {}
impl
ConnectorIntegration<
api::Authentication,
types::authentication::ConnectorAuthenticationRequestData,
types::authentication::AuthenticationResponseData,
> for Gpayments
{
}
impl
ConnectorIntegration<
api::PreAuthentication,
types::authentication::PreAuthNRequestData,
types::authentication::AuthenticationResponseData,
> for Gpayments
{
}
impl
ConnectorIntegration<
api::PostAuthentication,
types::authentication::ConnectorPostAuthenticationRequestData,
types::authentication::AuthenticationResponseData,
> for Gpayments
{
}