Skip to content

Hyperswitch v1.108.0

Latest
Compare
Choose a tag to compare
@sai-harsha-vardhan sai-harsha-vardhan released this 06 May 10:14
· 161 commits to main since this release

1.108.0 (2024-05-03)

Docker Release

v1.108.0 (with KMS)

v1.108.0-standalone (without KMS)

Features

  • connector:
    • [3dsecure.io] Add threedsecureio three_ds authentication connector (#4004)
    • [Checkout] add support for external authentication for checkout connector (#4006)
    • [AUTHORIZEDOTNET] Audit Connector (#4035)
    • [billwerk] implement payment and refund flows (#4245)
    • [Netcetera] Integrate netcetera connector with pre authentication flow (#4293)
    • [NMI] External 3DS flow for Cards (#4385)
    • [Netcetera] Implement authentication flow for netcetera (#4334)
    • [Netcetera] Add webhook support for netcetera (#4382)
    • [BOA] implement mandates for cards and wallets (#4232)
    • [Ebanx] Add payout flows (#4146)
    • [Paypal] Add payout flow for wallet(Paypal and Venmo) (#4406)
    • [BOA/Cybersource] add avs_response and cvv validation result in the response (#4376)
    • [Cybersource] Add NTID flow for cybersource (#4193)
  • Add api_models for external 3ds authentication flow (#3858)
  • Add core functions for external authentication (#3969)
  • Confirm flow and authorization api changes for external authentication (#4015)
  • Add incoming header request logs (#3939)
  • Add payments authentication api flow (#3996)
  • Add routing support for token-based mit payments (#4012)
  • Add local bank transfer payment method (#4294)
  • Add external authentication webhooks flow (#4339)
  • Add retrieve poll status api (#4358)
  • Handle authorization for frictionless flow in external 3ds flow (#4471)
  • Customer kv impl (#4267)
  • Add cypress test cases (#4271)
  • Add audit events scaffolding (#3863)
  • Add APIs to list webhook events and webhook delivery attempts (#4131)
  • Add events framework for registering events (#4115)
  • Add payment cancel events (#4166)
  • Dashboard globalsearch apis (#3831)
  • Add kv support for mandate (#4275)
  • Allow off-session payments using payment_method_id (#4132)
  • Added display_sdk_only option for displaying only sdk without payment details (#4363)
  • Add support for saved payment method option for payment link (#4373)
  • API to list countries and currencies supported by a country and payment method type (#4126)
  • Added kv support for payment_methods table (#4311)
  • Implement Single Connector Retry for Payouts (#3908)
  • Implement KVRouterStore (#3889)
  • Implement list and filter APIs (#3651)
  • Support different pm types in PM auth (#3114)
  • Add new API get the user and role details of specific user (#3988)
  • Implement automatic retries for failed webhook deliveries using scheduler (#3842)
  • Allow manually retrying delivery of outgoing webhooks (#4176)
  • Store payment check codes and authentication data from processors (#3958)
  • Stripe connect integration for payouts (#2041)
  • Add support for merchant to pass public key and ttl for encrypting payload (#4456)
  • Add an api for retrieving the extended card info from redis (#4484)

Refactors/Bug Fixes

  • Use fallback to connector_name if merchant_connector_id is not present (#4503)
  • Use first_name if last_name is not passed (#4360)
  • Generate payment_id if not sent (#4125)
  • Send valid sdk information in authentication flow netcetera (#4474)
  • Fix wallet token deserialization error (#4133)
  • Amount received should be zero for pending and failed status (#4331)
  • Amount capturable remain same for processing status in capture (#4229)
  • Fix 3DS mandates, for the connector _mandate_details to be stored in the payment_methods table (#4323)
  • Handle card duplication in payouts flow (#4013)
  • Give higher precedence to connector mandate id over network txn id in mandates (#4073)
  • Store network transaction id only when pg_agnostic config is enabled in the authorize_flow (#4318)
  • Insert locker_id as null in case of payment method not getting stored in locker (#3919)
  • Update payment method status only if existing status is not active (#4149)
  • Fix token fetch logic in complete authorize flow for three ds payments (#4052)
  • Handle redirection to return_url from nested iframe in separate 3ds flow (#4164)
  • Capture billing country in payments request (#4347)
  • Make payment_instrument optional (#4389)
  • Remove enabled payment methods for payouts processor (#3913)
  • Pass payment method billing to the connector module (#3828)
  • Use billing.first_name instead of card_holder_name (#4239)
  • Updated payments response with payment_method_id & payment_method_status (#3883)
  • Log the appropriate error message if the card fails to get saved in locker (#4296)
  • Make performance optimisation for payment_link (#4092)
  • Decouple shimmer css from main payment_link css for better performance (#4286)
  • Add a trait to retrieve billing from payment method data (#4095)
  • Filter applepay payment method from mca based on customer pm (#3953)
  • Enable country currency filter for cards (#4056)
  • Add network_transaction_id column in the payment_methods table (#4005)
  • Revamp payment methods update endpoint (#4305)
  • Store card_network in locker (#4425)
  • Deprecate Signin, Verify email and Invite v1 APIs (#4465)
  • Use single purpose token and auth to accept invite (#4498)
  • [Checkout] change payment and webhooks API contract (#4023)

Compatibility

This version of the Hyperswitch App server is compatible with the following versions of other components:

Database Migrations

Click to view database migrations
-- DB Difference BETWEEN v1.107.0 AND v1.108.0
CREATE TABLE IF NOT EXISTS authentication (
    authentication_id VARCHAR(64) NOT NULL,
    merchant_id VARCHAR(64) NOT NULL,
    authentication_connector VARCHAR(64) NOT NULL,
    connector_authentication_id VARCHAR(64),
    authentication_data JSONB,
    payment_method_id VARCHAR(64) NOT NULL,
    authentication_type VARCHAR(64),
    authentication_status VARCHAR(64) NOT NULL,
    authentication_lifecycle_status VARCHAR(64) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT now()::TIMESTAMP,
    modified_at TIMESTAMP NOT NULL DEFAULT now()::TIMESTAMP,
    error_message VARCHAR(64),
    error_code VARCHAR(64),
    PRIMARY KEY (authentication_id)
);

-- Your SQL goes here
ALTER TABLE payment_attempt
ADD COLUMN IF NOT EXISTS external_three_ds_authentication_attempted BOOLEAN DEFAULT FALSE,
ADD COLUMN IF NOT EXISTS authentication_connector VARCHAR(64),
ADD COLUMN IF NOT EXISTS authentication_id VARCHAR(64);

-- Your SQL goes here
ALTER TABLE payment_intent
ADD COLUMN IF NOT EXISTS request_external_three_ds_authentication BOOLEAN;

-- Your SQL goes here
ALTER TYPE "ConnectorType"
ADD VALUE IF NOT EXISTS 'authentication_processor';

-- Your SQL goes here
ALTER TABLE authentication
ADD COLUMN IF NOT EXISTS connector_metadata JSONB DEFAULT NULL;

-- Your SQL goes here
ALTER TABLE payment_attempt
ADD COLUMN IF NOT EXISTS payment_method_billing_address_id VARCHAR(64);

-- Your SQL goes here
ALTER TYPE "PaymentSource"
ADD VALUE 'webhook';

ALTER TYPE "PaymentSource"
ADD VALUE 'external_authenticator';

ALTER TABLE PAYOUTS
ADD COLUMN profile_id VARCHAR(64);

UPDATE PAYOUTS AS PO
SET profile_id = POA.profile_id
FROM PAYOUT_ATTEMPT AS POA
WHERE PO.payout_id = POA.payout_id;

ALTER TABLE PAYOUTS
ALTER COLUMN profile_id
SET NOT NULL;

ALTER TABLE PAYOUTS
ADD COLUMN status "PayoutStatus";

UPDATE PAYOUTS AS PO
SET status = POA.status
FROM PAYOUT_ATTEMPT AS POA
WHERE PO.payout_id = POA.payout_id;

ALTER TABLE PAYOUTS
ALTER COLUMN status
SET NOT NULL;

-- Your SQL goes here
ALTER TABLE business_profile
ADD COLUMN IF NOT EXISTS authentication_connector_details JSONB NULL;

-- The following queries must be run before the newer version of the application is deployed.
ALTER TABLE events
ADD COLUMN merchant_id VARCHAR(64) DEFAULT NULL,
ADD COLUMN business_profile_id VARCHAR(64) DEFAULT NULL,
ADD COLUMN primary_object_created_at TIMESTAMP DEFAULT NULL,
ADD COLUMN idempotent_event_id VARCHAR(64) DEFAULT NULL,
ADD COLUMN initial_attempt_id VARCHAR(64) DEFAULT NULL,
ADD COLUMN request BYTEA DEFAULT NULL,
ADD COLUMN response BYTEA DEFAULT NULL;

UPDATE events
SET idempotent_event_id = event_id
WHERE idempotent_event_id IS NULL;

UPDATE events
SET initial_attempt_id = event_id
WHERE initial_attempt_id IS NULL;

ALTER TABLE events
ADD CONSTRAINT idempotent_event_id_unique UNIQUE (idempotent_event_id);

-- Your SQL goes here
ALTER TABLE payment_methods
ADD COLUMN network_transaction_id VARCHAR(255) DEFAULT NULL;

-- Your SQL goes here
ALTER TABLE authentication
ADD COLUMN IF NOT EXISTS maximum_supported_version JSONB,
ADD COLUMN IF NOT EXISTS threeds_server_transaction_id VARCHAR(64),
ADD COLUMN IF NOT EXISTS cavv VARCHAR(64),
ADD COLUMN IF NOT EXISTS authentication_flow_type VARCHAR(64),
ADD COLUMN IF NOT EXISTS message_version JSONB,
ADD COLUMN IF NOT EXISTS eci VARCHAR(64),
ADD COLUMN IF NOT EXISTS trans_status VARCHAR(64),
ADD COLUMN IF NOT EXISTS acquirer_bin VARCHAR(64),
ADD COLUMN IF NOT EXISTS acquirer_merchant_id VARCHAR(64),
ADD COLUMN IF NOT EXISTS three_ds_method_data VARCHAR,
ADD COLUMN IF NOT EXISTS three_ds_method_url VARCHAR,
ADD COLUMN IF NOT EXISTS acs_url VARCHAR,
ADD COLUMN IF NOT EXISTS challenge_request VARCHAR,
ADD COLUMN IF NOT EXISTS acs_reference_number VARCHAR,
ADD COLUMN IF NOT EXISTS acs_trans_id VARCHAR,
ADD COLUMN IF NOT EXISTS three_dsserver_trans_id VARCHAR,
ADD COLUMN IF NOT EXISTS acs_signed_content VARCHAR,
ADD COLUMN IF NOT EXISTS connector_metadata JSONB;

-- Your SQL goes here
ALTER TABLE payment_methods
ADD COLUMN IF NOT EXISTS client_secret VARCHAR(128) DEFAULT NULL;

ALTER TABLE payment_methods
ALTER COLUMN payment_method DROP NOT NULL;

CREATE UNIQUE INDEX events_merchant_id_event_id_index ON events (merchant_id, event_id);

CREATE INDEX events_merchant_id_initial_attempt_id_index ON events (merchant_id, initial_attempt_id);

CREATE INDEX events_merchant_id_initial_events_index ON events (merchant_id, (event_id = initial_attempt_id));

CREATE INDEX events_business_profile_id_initial_attempt_id_index ON events (business_profile_id, initial_attempt_id);

CREATE INDEX events_business_profile_id_initial_events_index ON events (
business_profile_id,
(event_id = initial_attempt_id)
);

CREATE TYPE "WebhookDeliveryAttempt" AS ENUM (
'initial_attempt',
'automatic_retry',
'manual_retry'
);

ALTER TABLE events
ADD COLUMN delivery_attempt "WebhookDeliveryAttempt" DEFAULT NULL;

-- Your SQL goes here
ALTER TABLE authentication
ADD COLUMN profile_id VARCHAR(64) NOT NULL;

-- Your SQL goes here
ALTER TABLE authentication
ADD COLUMN payment_id VARCHAR(255);

-- Your SQL goes here
ALTER TYPE "DashboardMetadata"
ADD VALUE IF NOT EXISTS 'onboarding_survey';

-- Your SQL goes here
ALTER TABLE authentication
ADD COLUMN merchant_connector_id VARCHAR(128) NOT NULL;

Caution

Proceed with caution when running the following migrations as they are destructive.

Click here to view database migrations to be run after the newer version is deployed
-- Running these queries can even be deferred for some time (a couple of weeks or even a month) until the
-- new version being deployed is considered stable.
-- Make `event_id` primary key instead of `id`
ALTER TABLE events DROP CONSTRAINT events_pkey;

ALTER TABLE events ADD PRIMARY KEY (event_id);

ALTER TABLE events DROP CONSTRAINT event_id_unique;

-- Dropping unused columns
ALTER TABLE events
DROP COLUMN id,
DROP COLUMN intent_reference_id;

Configuration Changes

Diff of configuration changes between v1.107.0 and v1.108.0

diff --git a/config/deployments/production.toml b/config/deployments/production.toml
index 4be067dade24..1bc4319b2d37 100644
--- a/config/deployments/production.toml
+++ b/config/deployments/production.toml
@@ -17,13 +17,15 @@ payout_connector_list = "wise"
 
 [connectors]
 aci.base_url = "https://eu-test.oppwa.com/"
-adyen.base_url = "https://{{merchant_endpoint_prefix}}-checkout-live.adyenpayments.com/"
+adyen.base_url = "https://{{merchant_endpoint_prefix}}-checkout-live.adyenpayments.com/checkout/"
 adyen.secondary_base_url = "https://{{merchant_endpoint_prefix}}-pal-live.adyenpayments.com/"
 airwallex.base_url = "https://api-demo.airwallex.com/"
 applepay.base_url = "https://apple-pay-gateway.apple.com/"
-authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
+authorizedotnet.base_url = "https://api.authorize.net/xml/v1/request.api"
 bambora.base_url = "https://api.na.bambora.com"
 bankofamerica.base_url = "https://api.merchant-services.bankofamerica.com/"
+billwerk.base_url = "https://api.reepay.com/"
+billwerk.secondary_base_url = "https://card.reepay.com/"
 bitpay.base_url = "https://bitpay.com"
 bluesnap.base_url = "https://ws.bluesnap.com/"
 bluesnap.secondary_base_url = "https://pay.bluesnap.com/"
@@ -37,6 +39,7 @@ cryptopay.base_url = "https://business.cryptopay.me/"
 cybersource.base_url = "https://api.cybersource.com/"
 dlocal.base_url = "https://sandbox.dlocal.com/"
 dummyconnector.base_url = "http://localhost:8080/dummy-connector"
+ebanx.base_url = "https://sandbox.ebanxpay.com/"
 fiserv.base_url = "https://cert.api.fiservapps.com/"
 forte.base_url = "https://sandbox.forte.net/api/v3"
 globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/"
@@ -80,6 +83,9 @@ worldline.base_url = "https://eu.sandbox.api-ingenico.com/"
 worldpay.base_url = "https://try.access.worldpay.com/"
 zen.base_url = "https://api.zen.com/"
 zen.secondary_base_url = "https://secure.zen.com/"
+zsl.base_url = "https://api.sitoffalb.net/"
+threedsecureio.base_url = "https://service.3dsecure.io"
+netcetera.base_url = "https://{{merchant_endpoint_prefix}}.3ds-server.prev.netcetera-cloud-payment.ch"
 
 [delayed_session_response]
 connectors_with_delayed_session_response = "trustpay,payme"
@@ -102,7 +108,7 @@ refund_retrieve_duration = 500
 refund_retrieve_tolerance = 100
 refund_tolerance = 100
 refund_ttl = 172800
-slack_invite_url = "https://join.slack.com/t/hyperswitch-io/shared_invite/zt-1k6cz4lee-SAJzhz6bjmpp4jZCDOtOIg"
+slack_invite_url = "https://join.slack.com/t/hyperswitch-io/shared_invite/zt-2awm23agh-p_G5xNpziv6yAiedTkkqLg"
 
 [frm]
 enabled = false
@@ -111,11 +117,11 @@ enabled = false
 bank_debit.ach.connector_list = "gocardless"
 bank_debit.becs.connector_list = "gocardless"
 bank_debit.sepa.connector_list = "gocardless"
-card.credit.connector_list = "stripe,adyen,authorizedotnet,cybersource,globalpay,worldpay,multisafepay,nmi,nexinets,noon"
-card.debit.connector_list = "stripe,adyen,authorizedotnet,cybersource,globalpay,worldpay,multisafepay,nmi,nexinets,noon"
+card.credit.connector_list = "stripe,adyen,authorizedotnet,cybersource,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica"
+card.debit.connector_list = "stripe,adyen,authorizedotnet,cybersource,globalpay,worldpay,multisafepay,nmi,nexinets,noon,bankofamerica"
 pay_later.klarna.connector_list = "adyen"
-wallet.apple_pay.connector_list = "stripe,adyen,cybersource,noon"
-wallet.google_pay.connector_list = "stripe,adyen,cybersource"
+wallet.apple_pay.connector_list = "stripe,adyen,cybersource,noon,bankofamerica"
+wallet.google_pay.connector_list = "stripe,adyen,cybersource,bankofamerica"
 wallet.paypal.connector_list = "adyen"
 bank_redirect.ideal.connector_list = "stripe,adyen,globalpay"
 bank_redirect.sofort.connector_list = "stripe,adyen,globalpay"
@@ -285,6 +291,9 @@ pse = { country = "CO", currency = "COP" }
 red_compra = { country = "CL", currency = "CLP" }
 red_pagos = { country = "UY", currency = "UYU" }
 
+[pm_filters.zsl]
+local_bank_transfer = { country = "CN", currency = "CNY" }
+
 [temp_locker_enable_config]
 bluesnap.payment_method = "card"
 nuvei.payment_method = "card"
@@ -304,9 +313,13 @@ payme = { long_lived_token = false, payment_method = "card" }
 square = { long_lived_token = false, payment_method = "card" }
 stax = { long_lived_token = true, payment_method = "card,bank_debit" }
 stripe = { long_lived_token = false, payment_method = "wallet", payment_method_type = { list = "google_pay", type = "disable_only" } }
+billwerk = {long_lived_token = false, payment_method = "card"}
 
 [webhooks]
 outgoing_enabled = true
 
 [webhook_source_verification_call]
 connectors_with_webhook_source_verification_call = "paypal"
+
+[unmasked_headers]
+keys = "user-agent"

Full Changelog: v1.107.0...v1.108.0