feat(global-search): dashboard globalsearch apis (#3831)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
ivor-juspay
2024-03-12 13:21:09 +05:30
committed by GitHub
parent 45ed56f165
commit ac8ddd4020
16 changed files with 1133 additions and 349 deletions

684
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -54,10 +54,10 @@ use_legacy_version = false # Resp protocol for fred crate (set this to tr
stream_read_count = 1 # Default number of entries to read from stream if not provided in stream read options
auto_pipeline = true # Whether or not the client should automatically pipeline commands across tasks when possible.
disable_auto_backpressure = false # Whether or not to disable the automatic backpressure features when pipelining is enabled.
max_in_flight_commands = 5000 # The maximum number of in-flight commands (per connection) before backpressure will be applied.
default_command_timeout = 30 # An optional timeout to apply to all commands. In seconds
unresponsive_timeout = 10 # An optional timeout for Unresponsive commands in seconds. This should be less than default_command_timeout.
max_feed_count = 200 # The maximum number of frames that will be fed to a socket before flushing.
max_in_flight_commands = 5000 # The maximum number of in-flight commands (per connection) before backpressure will be applied.
default_command_timeout = 30 # An optional timeout to apply to all commands. In seconds
unresponsive_timeout = 10 # An optional timeout for Unresponsive commands in seconds. This should be less than default_command_timeout.
max_feed_count = 200 # The maximum number of frames that will be fed to a socket before flushing.
# This section provides configs for currency conversion api
[forex_api]
@ -298,9 +298,9 @@ lock_ttl = 160 # the ttl being the expiry (in seconds)
# Scheduler server configuration
[scheduler.server]
port = 3000 # Port on which the server will listen for incoming requests
host = "127.0.0.1" # Host IP address to bind the server to
workers = 1 # Number of actix workers to handle incoming requests concurrently
port = 3000 # Port on which the server will listen for incoming requests
host = "127.0.0.1" # Host IP address to bind the server to
workers = 1 # Number of actix workers to handle incoming requests concurrently
batch_size = 200 # Specifies the batch size the producer will push under a single entry in the redis queue
@ -321,10 +321,10 @@ paypal = { currency = "USD,INR", country = "US" }
# If either currency or country isn't provided then, all possible values are accepted
[cors]
max_age = 30 # Maximum time (in seconds) for which this CORS request may be cached.
origins = "http://localhost:8080" # List of origins that are allowed to make requests.
max_age = 30 # Maximum time (in seconds) for which this CORS request may be cached.
origins = "http://localhost:8080" # List of origins that are allowed to make requests.
allowed_methods = "GET,POST,PUT,DELETE" # List of methods that are allowed
wildcard_origin = false # If true, allows any origin to make requests
wildcard_origin = false # If true, allows any origin to make requests
# EmailClient configuration. Only applicable when the `email` feature flag is enabled.
[email]
@ -357,7 +357,7 @@ bluesnap = { payment_method = "card" }
bankofamerica = { payment_method = "card" }
cybersource = { payment_method = "card" }
nmi = { payment_method = "card" }
payme = {payment_method = "card" }
payme = { payment_method = "card" }
[dummy_connector]
enabled = true # Whether dummy connector is enabled or not
@ -380,21 +380,21 @@ slack_invite_url = "https://www.example.com/" # Slack invite url for hyperswit
discord_invite_url = "https://www.example.com/" # Discord invite url for hyperswitch
[mandates.supported_payment_methods]
card.credit = { connector_list = "stripe,adyen,cybersource" } # Mandate supported payment method type and connector for card
wallet.paypal = { connector_list = "adyen" } # Mandate supported payment method type and connector for wallets
pay_later.klarna = { connector_list = "adyen" } # Mandate supported payment method type and connector for pay_later
bank_debit.ach = { connector_list = "gocardless" } # Mandate supported payment method type and connector for bank_debit
bank_debit.becs = { connector_list = "gocardless" } # Mandate supported payment method type and connector for bank_debit
bank_debit.sepa = { connector_list = "gocardless" } # Mandate supported payment method type and connector for bank_debit
bank_redirect.ideal = {connector_list = "stripe,adyen,globalpay"} # Mandate supported payment method type and connector for bank_redirect
bank_redirect.sofort = {connector_list = "stripe,adyen,globalpay"}
card.credit = { connector_list = "stripe,adyen,cybersource" } # Mandate supported payment method type and connector for card
wallet.paypal = { connector_list = "adyen" } # Mandate supported payment method type and connector for wallets
pay_later.klarna = { connector_list = "adyen" } # Mandate supported payment method type and connector for pay_later
bank_debit.ach = { connector_list = "gocardless" } # Mandate supported payment method type and connector for bank_debit
bank_debit.becs = { connector_list = "gocardless" } # Mandate supported payment method type and connector for bank_debit
bank_debit.sepa = { connector_list = "gocardless" } # Mandate supported payment method type and connector for bank_debit
bank_redirect.ideal = { connector_list = "stripe,adyen,globalpay" } # Mandate supported payment method type and connector for bank_redirect
bank_redirect.sofort = { connector_list = "stripe,adyen,globalpay" }
wallet.apple_pay = { connector_list = "stripe,adyen,cybersource,noon" }
bank_redirect.giropay = {connector_list = "adyen,globalpay"}
bank_redirect.giropay = { connector_list = "adyen,globalpay" }
[mandates.update_mandate_supported]
card.credit ={connector_list ="cybersource"} # Update Mandate supported payment method type and connector for card
card.debit = {connector_list ="cybersource"} # Update Mandate supported payment method type and connector for card
card.credit = { connector_list = "cybersource" } # Update Mandate supported payment method type and connector for card
card.debit = { connector_list = "cybersource" } # Update Mandate supported payment method type and connector for card
# Required fields info used while listing the payment_method_data
[required_fields.pay_later] # payment_method = "pay_later"
@ -412,9 +412,9 @@ afterpay_clearpay = { fields = { stripe = [ # payment_method_type = afterpay_cle
payout_eligibility = true # Defaults the eligibility of a payout method to true in case connector does not provide checks for payout eligibility
[pm_filters.adyen]
sofort = { country = "AT,BE,DE,ES,CH,NL", currency = "CHF,EUR"}
sofort = { country = "AT,BE,DE,ES,CH,NL", currency = "CHF,EUR" }
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" }
klarna = { country = "AU,AT,BE,CA,CZ,DK,FI,FR,DE,GR,IE,IT,NO,PL,PT,RO,ES,SE,CH,NL,GB,US", currency = "AUD,EUR,CAD,CZK,DKK,NOK,PLN,RON,SEK,CHF,GBP,USD"}
klarna = { country = "AU,AT,BE,CA,CZ,DK,FI,FR,DE,GR,IE,IT,NO,PL,PT,RO,ES,SE,CH,NL,GB,US", currency = "AUD,EUR,CAD,CZK,DKK,NOK,PLN,RON,SEK,CHF,GBP,USD" }
ideal = { country = "NL", currency = "EUR" }
online_banking_fpx = { country = "MY", currency = "MYR" }
online_banking_thailand = { country = "TH", currency = "THB" }
@ -442,7 +442,7 @@ pay_easy = { country = "JP", currency = "JPY" }
boleto = { country = "BR", currency = "BRL" }
[pm_filters.volt]
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"}
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.zen]
credit = { not_available_flows = { capture_method = "manual" } }
@ -566,22 +566,36 @@ dispute_analytics_topic = "topic" # Kafka topic to be used for Dispute event
# File storage configuration
[file_storage]
file_storage_backend = "aws_s3" # File storage backend to be used
file_storage_backend = "aws_s3" # File storage backend to be used
[file_storage.aws_s3]
region = "us-east-1" # The AWS region used by the AWS S3 for file storage
bucket_name = "bucket1" # The AWS S3 bucket name for file storage
region = "us-east-1" # The AWS region used by the AWS S3 for file storage
bucket_name = "bucket1" # The AWS S3 bucket name for file storage
[secrets_management]
secrets_manager = "aws_kms" # Secrets manager client to be used
secrets_manager = "aws_kms" # Secrets manager client to be used
[secrets_management.aws_kms]
key_id = "kms_key_id" # The AWS key ID used by the KMS SDK for decrypting data.
region = "kms_region" # The AWS region used by the KMS SDK for decrypting data.
key_id = "kms_key_id" # The AWS key ID used by the KMS SDK for decrypting data.
region = "kms_region" # The AWS region used by the KMS SDK for decrypting data.
[encryption_management]
encryption_manager = "aws_kms" # Encryption manager client to be used
encryption_manager = "aws_kms" # Encryption manager client to be used
[encryption_management.aws_kms]
key_id = "kms_key_id" # The AWS key ID used by the KMS SDK for decrypting data.
region = "kms_region" # The AWS region used by the KMS SDK for decrypting data.
key_id = "kms_key_id" # The AWS key ID used by the KMS SDK for decrypting data.
region = "kms_region" # The AWS region used by the KMS SDK for decrypting data.
[opensearch]
host = "https://localhost:9200"
[opensearch.auth]
auth = "basic"
username = "admin"
password = "admin"
region = "eu-central-1"
[opensearch.indexes]
payment_attempts = "hyperswitch-payment-attempt-events"
payment_intents = "hyperswitch-payment-intent-events"
refunds = "hyperswitch-refund-events"

View File

@ -42,13 +42,17 @@ client_secret = "paypal_client_secret"
partner_id = "paypal_partner_id"
[connector_request_reference_id_config]
merchant_ids_send_payment_id_as_connector_request_id = ["merchant_id_1", "merchant_id_2", "etc.,"]
merchant_ids_send_payment_id_as_connector_request_id = [
"merchant_id_1",
"merchant_id_2",
"etc.,",
]
[cors]
max_age = 30 # Maximum time (in seconds) for which this CORS request may be cached.
origins = "http://localhost:8080" # List of origins that are allowed to make requests.
max_age = 30 # Maximum time (in seconds) for which this CORS request may be cached.
origins = "http://localhost:8080" # List of origins that are allowed to make requests.
allowed_methods = "GET,POST,PUT,DELETE" # List of methods that are allowed
wildcard_origin = false # If true, allows any origin to make requests
wildcard_origin = false # If true, allows any origin to make requests
# EmailClient configuration. Only applicable when the `email` feature flag is enabled.
[email]
@ -160,21 +164,24 @@ https_url = "https://proxy_https_url" # Outgoing proxy https URL to proxy the HT
[redis]
host = "127.0.0.1"
port = 6379
pool_size = 5 # Number of connections to keep open
reconnect_max_attempts = 5 # Maximum number of reconnection attempts to make before failing. Set to 0 to retry forever.
reconnect_delay = 5 # Delay between reconnection attempts, in milliseconds
default_ttl = 300 # Default TTL for entries, in seconds
default_hash_ttl = 900 # Default TTL for hashes entries, in seconds
use_legacy_version = false # RESP protocol for fred crate (set this to true if using RESPv2 or redis version < 6)
stream_read_count = 1 # Default number of entries to read from stream if not provided in stream read options
auto_pipeline = true # Whether or not the client should automatically pipeline commands across tasks when possible.
disable_auto_backpressure = false # Whether or not to disable the automatic backpressure features when pipelining is enabled.
pool_size = 5 # Number of connections to keep open
reconnect_max_attempts = 5 # Maximum number of reconnection attempts to make before failing. Set to 0 to retry forever.
reconnect_delay = 5 # Delay between reconnection attempts, in milliseconds
default_ttl = 300 # Default TTL for entries, in seconds
default_hash_ttl = 900 # Default TTL for hashes entries, in seconds
use_legacy_version = false # RESP protocol for fred crate (set this to true if using RESPv2 or redis version < 6)
stream_read_count = 1 # Default number of entries to read from stream if not provided in stream read options
auto_pipeline = true # Whether or not the client should automatically pipeline commands across tasks when possible.
disable_auto_backpressure = false # Whether or not to disable the automatic backpressure features when pipelining is enabled.
max_in_flight_commands = 5000 # The maximum number of in-flight commands (per connection) before backpressure will be applied.
default_command_timeout = 30 # An optional timeout to apply to all commands. In seconds
default_command_timeout = 30 # An optional timeout to apply to all commands. In seconds
unresponsive_timeout = 10 # An optional timeout for Unresponsive commands in seconds. This should be less than default_command_timeout.
max_feed_count = 200 # The maximum number of frames that will be fed to a socket before flushing.
cluster_enabled = true # boolean
cluster_urls = ["redis.cluster.uri-1:8080", "redis.cluster.uri-2:4115"] # List of redis cluster urls
max_feed_count = 200 # The maximum number of frames that will be fed to a socket before flushing.
cluster_enabled = true # boolean
cluster_urls = [
"redis.cluster.uri-1:8080",
"redis.cluster.uri-2:4115",
] # List of redis cluster urls
# Replica SQL data store credentials
[replica_database]
@ -193,6 +200,20 @@ payment_function = "report_download_config_payment_function" # Config to downloa
refund_function = "report_download_config_refund_function" # Config to download refund report
region = "report_download_config_region" # Region of the bucket
[opensearch]
host = "https://localhost:9200"
[opensearch.auth]
auth = "basic"
username = "admin"
password = "admin"
region = "eu-central-1"
[opensearch.indexes]
payment_attempts = "hyperswitch-payment-attempt-events"
payment_intents = "hyperswitch-payment-intent-events"
refunds = "hyperswitch-refund-events"
# This section provides some secret values.
[secrets]
master_enc_key = "sample_key" # Master Encryption key used to encrypt merchant wise encryption key. Should be 32-byte long.
@ -213,15 +234,15 @@ shutdown_timeout = 30
request_body_limit = 32_768
[secrets_management]
secrets_manager = "aws_kms" # Secrets manager client to be used
secrets_manager = "aws_kms" # Secrets manager client to be used
[secrets_management.aws_kms]
key_id = "kms_key_id" # The AWS key ID used by the KMS SDK for decrypting data.
region = "kms_region" # The AWS region used by the KMS SDK for decrypting data.
key_id = "kms_key_id" # The AWS key ID used by the KMS SDK for decrypting data.
region = "kms_region" # The AWS region used by the KMS SDK for decrypting data.
[encryption_management]
encryption_manager = "aws_kms" # Encryption manager client to be used
encryption_manager = "aws_kms" # Encryption manager client to be used
[encryption_management.aws_kms]
key_id = "kms_key_id" # The AWS key ID used by the KMS SDK for decrypting data.
region = "kms_region" # The AWS region used by the KMS SDK for decrypting data.
key_id = "kms_key_id" # The AWS key ID used by the KMS SDK for decrypting data.
region = "kms_region" # The AWS region used by the KMS SDK for decrypting data.

View File

@ -273,7 +273,7 @@ adyen = { banks = "blik_psp,place_zipko,m_bank,pay_with_ing,santander_przelew24,
stripe = { banks = "alior_bank,bank_millennium,bank_nowy_bfg_sa,bank_pekao_sa,banki_spbdzielcze,blik,bnp_paribas,boz,citi,credit_agricole,e_transfer_pocztowy24,getin_bank,idea_bank,inteligo,mbank_mtransfer,nest_przelew,noble_pay,pbac_z_ipko,plus_bank,santander_przelew24,toyota_bank,volkswagen_bank" }
[bank_config.open_banking_uk]
adyen = { banks = "aib,bank_of_scotland,danske_bank,first_direct,first_trust,halifax,lloyds,monzo,nat_west,nationwide_bank,royal_bank_of_scotland,starling,tsb_bank,tesco_bank,ulster_bank,barclays,hsbc_bank,revolut,santander_przelew24,open_bank_success,open_bank_failure,open_bank_cancelled"}
adyen = { banks = "aib,bank_of_scotland,danske_bank,first_direct,first_trust,halifax,lloyds,monzo,nat_west,nationwide_bank,royal_bank_of_scotland,starling,tsb_bank,tesco_bank,ulster_bank,barclays,hsbc_bank,revolut,santander_przelew24,open_bank_success,open_bank_failure,open_bank_cancelled" }
[bank_config.online_banking_fpx]
adyen.banks = "affin_bank,agro_bank,alliance_bank,am_bank,bank_islam,bank_muamalat,bank_rakyat,bank_simpanan_nasional,cimb_bank,hong_leong_bank,hsbc_bank,kuwait_finance_house,maybank,ocbc_bank,public_bank,rhb_bank,standard_chartered_bank,uob_bank"
@ -306,7 +306,7 @@ ideal = { country = "NL", currency = "EUR" }
cashapp = { country = "US", currency = "USD" }
[pm_filters.volt]
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"}
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" }
@ -316,54 +316,54 @@ mobile_pay = { country = "DK,FI", currency = "DKK,SEK,NOK,EUR" }
ali_pay = { country = "AU,JP,HK,SG,MY,TH,ES,GB,SE,NO,AT,NL,DE,CY,CH,BE,FR,DK,FI,RO,MT,SI,GR,PT,IE,IT,CA,US", currency = "USD,EUR,GBP,JPY,AUD,SGD,CHF,SEK,NOK,NZD,THB,HKD,CAD" }
we_chat_pay = { country = "AU,NZ,CN,JP,HK,SG,ES,GB,SE,NO,AT,NL,DE,CY,CH,BE,FR,DK,LI,MT,SI,GR,PT,IT,CA,US", currency = "AUD,CAD,CNY,EUR,GBP,HKD,JPY,NZD,SGD,USD" }
mb_way = { country = "PT", currency = "EUR" }
klarna = { country = "AU,AT,BE,CA,CZ,DK,FI,FR,DE,GR,IE,IT,NO,PL,PT,RO,ES,SE,CH,NL,GB,US", currency = "AUD,EUR,CAD,CZK,DKK,NOK,PLN,RON,SEK,CHF,GBP,USD"}
klarna = { country = "AU,AT,BE,CA,CZ,DK,FI,FR,DE,GR,IE,IT,NO,PL,PT,RO,ES,SE,CH,NL,GB,US", currency = "AUD,EUR,CAD,CZK,DKK,NOK,PLN,RON,SEK,CHF,GBP,USD" }
affirm = { country = "US", currency = "USD" }
afterpay_clearpay = { country = "AU,NZ,ES,GB,FR,IT,CA,US", currency = "GBP" }
pay_bright = { country = "CA", currency = "CAD" }
walley = { country = "SE,NO,DK,FI", currency = "DKK,EUR,NOK,SEK" }
giropay = { country = "DE", currency = "EUR" }
eps = { country = "AT", currency = "EUR" }
sofort = {not_available_flows = { capture_method = "manual" }, country = "AT,BE,DE,ES,CH,NL", currency = "CHF,EUR"}
sofort = { not_available_flows = { capture_method = "manual" }, country = "AT,BE,DE,ES,CH,NL", currency = "CHF,EUR" }
ideal = { not_available_flows = { capture_method = "manual" }, country = "NL", currency = "EUR" }
blik = {country = "PL", currency = "PLN"}
trustly = {country = "ES,GB,SE,NO,AT,NL,DE,DK,FI,EE,LT,LV", currency = "CZK,DKK,EUR,GBP,NOK,SEK"}
online_banking_czech_republic = {country = "CZ", currency = "EUR,CZK"}
online_banking_finland = {country = "FI", currency = "EUR"}
online_banking_poland = {country = "PL", currency = "PLN"}
online_banking_slovakia = {country = "SK", currency = "EUR,CZK"}
bancontact_card = {country = "BE", currency = "EUR"}
ach = {country = "US", currency = "USD"}
bacs = {country = "GB", currency = "GBP"}
sepa = {country = "ES,SK,AT,NL,DE,BE,FR,FI,PT,IE,EE,LT,LV,IT", currency = "EUR"}
ali_pay_hk = {country = "HK", currency = "HKD"}
bizum = {country = "ES", currency = "EUR"}
go_pay = {country = "ID", currency = "IDR"}
kakao_pay = {country = "KR", currency = "KRW"}
momo = {country = "VN", currency = "VND"}
gcash = {country = "PH", currency = "PHP"}
online_banking_fpx = {country = "MY", currency = "MYR"}
online_banking_thailand = {country = "TH", currency = "THB"}
touch_n_go = {country = "MY", currency = "MYR"}
atome = {country = "MY,SG", currency = "MYR,SGD"}
swish = {country = "SE", currency = "SEK"}
permata_bank_transfer = {country = "ID", currency = "IDR"}
bca_bank_transfer = {country = "ID", currency = "IDR"}
bni_va = {country = "ID", currency = "IDR"}
bri_va = {country = "ID", currency = "IDR"}
cimb_va = {country = "ID", currency = "IDR"}
danamon_va = {country = "ID", currency = "IDR"}
mandiri_va = {country = "ID", currency = "IDR"}
alfamart = {country = "ID", currency = "IDR"}
indomaret = {country = "ID", currency = "IDR"}
open_banking_uk = {country = "GB", currency = "GBP"}
oxxo = {country = "MX", currency = "MXN"}
pay_safe_card = {country = "AT,AU,BE,BR,BE,CA,HR,CY,CZ,DK,FI,FR,GE,DE,GI,HU,IS,IE,KW,LV,IE,LI,LT,LU,MT,MX,MD,ME,NL,NZ,NO,PY,PE,PL,PT,RO,SA,RS,SK,SI,ES,SE,CH,TR,AE,GB,US,UY", currency = "EUR,AUD,BRL,CAD,CZK,DKK,GEL,GIP,HUF,KWD,CHF,MXN,MDL,NZD,NOK,PYG,PEN,PLN,RON,SAR,RSD,SEK,TRY,AED,GBP,USD,UYU"}
seven_eleven = {country = "JP", currency = "JPY"}
lawson = {country = "JP", currency = "JPY"}
mini_stop = {country = "JP", currency = "JPY"}
family_mart = {country = "JP", currency = "JPY"}
seicomart = {country = "JP", currency = "JPY"}
pay_easy = {country = "JP", currency = "JPY"}
blik = { country = "PL", currency = "PLN" }
trustly = { country = "ES,GB,SE,NO,AT,NL,DE,DK,FI,EE,LT,LV", currency = "CZK,DKK,EUR,GBP,NOK,SEK" }
online_banking_czech_republic = { country = "CZ", currency = "EUR,CZK" }
online_banking_finland = { country = "FI", currency = "EUR" }
online_banking_poland = { country = "PL", currency = "PLN" }
online_banking_slovakia = { country = "SK", currency = "EUR,CZK" }
bancontact_card = { country = "BE", currency = "EUR" }
ach = { country = "US", currency = "USD" }
bacs = { country = "GB", currency = "GBP" }
sepa = { country = "ES,SK,AT,NL,DE,BE,FR,FI,PT,IE,EE,LT,LV,IT", currency = "EUR" }
ali_pay_hk = { country = "HK", currency = "HKD" }
bizum = { country = "ES", currency = "EUR" }
go_pay = { country = "ID", currency = "IDR" }
kakao_pay = { country = "KR", currency = "KRW" }
momo = { country = "VN", currency = "VND" }
gcash = { country = "PH", currency = "PHP" }
online_banking_fpx = { country = "MY", currency = "MYR" }
online_banking_thailand = { country = "TH", currency = "THB" }
touch_n_go = { country = "MY", currency = "MYR" }
atome = { country = "MY,SG", currency = "MYR,SGD" }
swish = { country = "SE", currency = "SEK" }
permata_bank_transfer = { country = "ID", currency = "IDR" }
bca_bank_transfer = { country = "ID", currency = "IDR" }
bni_va = { country = "ID", currency = "IDR" }
bri_va = { country = "ID", currency = "IDR" }
cimb_va = { country = "ID", currency = "IDR" }
danamon_va = { country = "ID", currency = "IDR" }
mandiri_va = { country = "ID", currency = "IDR" }
alfamart = { country = "ID", currency = "IDR" }
indomaret = { country = "ID", currency = "IDR" }
open_banking_uk = { country = "GB", currency = "GBP" }
oxxo = { country = "MX", currency = "MXN" }
pay_safe_card = { country = "AT,AU,BE,BR,BE,CA,HR,CY,CZ,DK,FI,FR,GE,DE,GI,HU,IS,IE,KW,LV,IE,LI,LT,LU,MT,MX,MD,ME,NL,NZ,NO,PY,PE,PL,PT,RO,SA,RS,SK,SI,ES,SE,CH,TR,AE,GB,US,UY", currency = "EUR,AUD,BRL,CAD,CZK,DKK,GEL,GIP,HUF,KWD,CHF,MXN,MDL,NZD,NOK,PYG,PEN,PLN,RON,SAR,RSD,SEK,TRY,AED,GBP,USD,UYU" }
seven_eleven = { country = "JP", currency = "JPY" }
lawson = { country = "JP", currency = "JPY" }
mini_stop = { country = "JP", currency = "JPY" }
family_mart = { country = "JP", currency = "JPY" }
seicomart = { country = "JP", currency = "JPY" }
pay_easy = { country = "JP", currency = "JPY" }
pix = { country = "BR", currency = "BRL" }
boleto = { country = "BR", currency = "BRL" }
@ -443,21 +443,21 @@ debit = { currency = "USD" }
stripe = { long_lived_token = false, payment_method = "wallet", payment_method_type = { type = "disable_only", list = "google_pay" } }
checkout = { long_lived_token = false, payment_method = "wallet", apple_pay_pre_decrypt_flow = "network_tokenization" }
stax = { long_lived_token = true, payment_method = "card,bank_debit" }
mollie = {long_lived_token = false, payment_method = "card"}
square = {long_lived_token = false, payment_method = "card"}
mollie = { long_lived_token = false, payment_method = "card" }
square = { long_lived_token = false, payment_method = "card" }
braintree = { long_lived_token = false, payment_method = "card" }
payme = {long_lived_token = false, payment_method = "card"}
gocardless = {long_lived_token = true, payment_method = "bank_debit"}
payme = { long_lived_token = false, payment_method = "card" }
gocardless = { long_lived_token = true, payment_method = "bank_debit" }
[temp_locker_enable_config]
stripe = {payment_method = "bank_transfer"}
nuvei = {payment_method = "card"}
shift4 = {payment_method = "card"}
bluesnap = {payment_method = "card"}
bankofamerica = {payment_method = "card"}
cybersource = {payment_method = "card"}
nmi = {payment_method = "card"}
payme = {payment_method = "card"}
stripe = { payment_method = "bank_transfer" }
nuvei = { payment_method = "card" }
shift4 = { payment_method = "card" }
bluesnap = { payment_method = "card" }
bankofamerica = { payment_method = "card" }
cybersource = { payment_method = "card" }
nmi = { payment_method = "card" }
payme = { payment_method = "card" }
[connector_customer]
connector_list = "gocardless,stax,stripe"
@ -496,16 +496,16 @@ wallet.apple_pay = { connector_list = "stripe,adyen,cybersource,noon" }
wallet.paypal = { connector_list = "adyen" }
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" }
bank_debit.ach = { connector_list = "gocardless"}
bank_debit.becs = { connector_list = "gocardless"}
bank_debit.sepa = { connector_list = "gocardless"}
bank_redirect.ideal = {connector_list = "stripe,adyen,globalpay"}
bank_redirect.sofort = {connector_list = "stripe,adyen,globalpay"}
bank_redirect.giropay = {connector_list = "adyen,globalpay"}
bank_debit.ach = { connector_list = "gocardless" }
bank_debit.becs = { connector_list = "gocardless" }
bank_debit.sepa = { connector_list = "gocardless" }
bank_redirect.ideal = { connector_list = "stripe,adyen,globalpay" }
bank_redirect.sofort = { connector_list = "stripe,adyen,globalpay" }
bank_redirect.giropay = { connector_list = "adyen,globalpay" }
[mandates.update_mandate_supported]
card.credit ={connector_list ="cybersource"}
card.debit = {connector_list ="cybersource"}
card.credit = { connector_list = "cybersource" }
card.debit = { connector_list = "cybersource" }
[connector_request_reference_id_config]
merchant_ids_send_payment_id_as_connector_request_id = []
@ -530,7 +530,7 @@ redis_expiry = 900
pm_auth_key = "Some_pm_auth_key"
[lock_settings]
redis_lock_expiry_seconds = 180 # 3 * 60 seconds
redis_lock_expiry_seconds = 180 # 3 * 60 seconds
delay_between_retries_in_milliseconds = 500
[kv_config]
@ -582,3 +582,17 @@ file_storage_backend = "file_system"
[unmasked_headers]
keys = "user-agent"
[opensearch]
host = "https://localhost:9200"
[opensearch.auth]
auth = "basic"
username = "admin"
password = "admin"
region = "eu-central-1"
[opensearch.indexes]
payment_attempts = "hyperswitch-payment-attempt-events"
payment_intents = "hyperswitch-payment-intent-events"
refunds = "hyperswitch-refund-events"

View File

@ -15,7 +15,7 @@ level = "DEBUG" # What you see in your terminal.
[log.telemetry]
traces_enabled = false # Whether traces are enabled.
metrics_enabled = true # Whether metrics are enabled.
metrics_enabled = true # Whether metrics are enabled.
ignore_errors = false # Whether to ignore errors during traces or metrics pipeline setup.
otel_exporter_otlp_endpoint = "https://otel-collector:4317" # Endpoint to send metrics and traces to.
use_xray_generator = false
@ -244,21 +244,21 @@ workers = 1
[tokenization]
stripe = { long_lived_token = false, payment_method = "wallet", payment_method_type = { type = "disable_only", list = "google_pay" } }
checkout = { long_lived_token = false, payment_method = "wallet", apple_pay_pre_decrypt_flow = "network_tokenization" }
mollie = {long_lived_token = false, payment_method = "card"}
mollie = { long_lived_token = false, payment_method = "card" }
stax = { long_lived_token = true, payment_method = "card,bank_debit" }
square = {long_lived_token = false, payment_method = "card"}
square = { long_lived_token = false, payment_method = "card" }
braintree = { long_lived_token = false, payment_method = "card" }
gocardless = {long_lived_token = true, payment_method = "bank_debit"}
gocardless = { long_lived_token = true, payment_method = "bank_debit" }
[temp_locker_enable_config]
stripe = {payment_method = "bank_transfer"}
nuvei = {payment_method = "card"}
shift4 = {payment_method = "card"}
bluesnap = {payment_method = "card"}
bankofamerica = {payment_method = "card"}
cybersource = {payment_method = "card"}
nmi = {payment_method = "card"}
payme = {payment_method = "card"}
stripe = { payment_method = "bank_transfer" }
nuvei = { payment_method = "card" }
shift4 = { payment_method = "card" }
bluesnap = { payment_method = "card" }
bankofamerica = { payment_method = "card" }
cybersource = { payment_method = "card" }
nmi = { payment_method = "card" }
payme = { payment_method = "card" }
[dummy_connector]
enabled = true
@ -284,38 +284,38 @@ discord_invite_url = "https://discord.gg/wJZ7DVW8mm"
payout_eligibility = true
[pm_filters.adyen]
online_banking_fpx = {country = "MY", currency = "MYR"}
online_banking_thailand = {country = "TH", currency = "THB"}
touch_n_go = {country = "MY", currency = "MYR"}
atome = {country = "MY,SG", currency = "MYR,SGD"}
swish = {country = "SE", currency = "SEK"}
permata_bank_transfer = {country = "ID", currency = "IDR"}
bca_bank_transfer = {country = "ID", currency = "IDR"}
bni_va = {country = "ID", currency = "IDR"}
bri_va = {country = "ID", currency = "IDR"}
cimb_va = {country = "ID", currency = "IDR"}
danamon_va = {country = "ID", currency = "IDR"}
mandiri_va = {country = "ID", currency = "IDR"}
alfamart = {country = "ID", currency = "IDR"}
indomaret = {country = "ID", currency = "IDR"}
open_banking_uk = {country = "GB", currency = "GBP"}
oxxo = {country = "MX", currency = "MXN"}
pay_safe_card = {country = "AT,AU,BE,BR,BE,CA,HR,CY,CZ,DK,FI,FR,GE,DE,GI,HU,IS,IE,KW,LV,IE,LI,LT,LU,MT,MX,MD,ME,NL,NZ,NO,PY,PE,PL,PT,RO,SA,RS,SK,SI,ES,SE,CH,TR,AE,GB,US,UY", currency = "EUR,AUD,BRL,CAD,CZK,DKK,GEL,GIP,HUF,KWD,CHF,MXN,MDL,NZD,NOK,PYG,PEN,PLN,RON,SAR,RSD,SEK,TRY,AED,GBP,USD,UYU"}
seven_eleven = {country = "JP", currency = "JPY"}
lawson = {country = "JP", currency = "JPY"}
mini_stop = {country = "JP", currency = "JPY"}
family_mart = {country = "JP", currency = "JPY"}
seicomart = {country = "JP", currency = "JPY"}
pay_easy = {country = "JP", currency = "JPY"}
online_banking_fpx = { country = "MY", currency = "MYR" }
online_banking_thailand = { country = "TH", currency = "THB" }
touch_n_go = { country = "MY", currency = "MYR" }
atome = { country = "MY,SG", currency = "MYR,SGD" }
swish = { country = "SE", currency = "SEK" }
permata_bank_transfer = { country = "ID", currency = "IDR" }
bca_bank_transfer = { country = "ID", currency = "IDR" }
bni_va = { country = "ID", currency = "IDR" }
bri_va = { country = "ID", currency = "IDR" }
cimb_va = { country = "ID", currency = "IDR" }
danamon_va = { country = "ID", currency = "IDR" }
mandiri_va = { country = "ID", currency = "IDR" }
alfamart = { country = "ID", currency = "IDR" }
indomaret = { country = "ID", currency = "IDR" }
open_banking_uk = { country = "GB", currency = "GBP" }
oxxo = { country = "MX", currency = "MXN" }
pay_safe_card = { country = "AT,AU,BE,BR,BE,CA,HR,CY,CZ,DK,FI,FR,GE,DE,GI,HU,IS,IE,KW,LV,IE,LI,LT,LU,MT,MX,MD,ME,NL,NZ,NO,PY,PE,PL,PT,RO,SA,RS,SK,SI,ES,SE,CH,TR,AE,GB,US,UY", currency = "EUR,AUD,BRL,CAD,CZK,DKK,GEL,GIP,HUF,KWD,CHF,MXN,MDL,NZD,NOK,PYG,PEN,PLN,RON,SAR,RSD,SEK,TRY,AED,GBP,USD,UYU" }
seven_eleven = { country = "JP", currency = "JPY" }
lawson = { country = "JP", currency = "JPY" }
mini_stop = { country = "JP", currency = "JPY" }
family_mart = { country = "JP", currency = "JPY" }
seicomart = { country = "JP", currency = "JPY" }
pay_easy = { country = "JP", currency = "JPY" }
boleto = { country = "BR", currency = "BRL" }
ideal = { country = "NL", currency = "EUR" }
klarna = { country = "AU,AT,BE,CA,CZ,DK,FI,FR,DE,GR,IE,IT,NO,PL,PT,RO,ES,SE,CH,NL,GB,US", currency = "AUD,EUR,CAD,CZK,DKK,NOK,PLN,RON,SEK,CHF,GBP,USD"}
klarna = { country = "AU,AT,BE,CA,CZ,DK,FI,FR,DE,GR,IE,IT,NO,PL,PT,RO,ES,SE,CH,NL,GB,US", currency = "AUD,EUR,CAD,CZK,DKK,NOK,PLN,RON,SEK,CHF,GBP,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" }
sofort = { country = "AT,BE,DE,ES,CH,NL", currency = "CHF,EUR"}
sofort = { country = "AT,BE,DE,ES,CH,NL", currency = "CHF,EUR" }
[pm_filters.volt]
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"}
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.zen]
credit = { not_available_flows = { capture_method = "manual" } }
@ -330,7 +330,7 @@ red_compra = { country = "CL", currency = "CLP" }
red_pagos = { country = "UY", currency = "UYU" }
[pm_filters.stripe]
cashapp = {country = "US", currency = "USD"}
cashapp = { country = "US", currency = "USD" }
[pm_filters.prophetpay]
card_redirect = { currency = "USD" }
@ -357,25 +357,25 @@ adyen.banks = "affin_bank,agro_bank,alliance_bank,am_bank,bank_islam,bank_muamal
adyen.banks = "bangkok_bank,krungsri_bank,krung_thai_bank,the_siam_commercial_bank,kasikorn_bank"
[bank_config.open_banking_uk]
adyen = { banks = "aib,bank_of_scotland,danske_bank,first_direct,first_trust,halifax,lloyds,monzo,nat_west,nationwide_bank,royal_bank_of_scotland,starling,tsb_bank,tesco_bank,ulster_bank,barclays,hsbc_bank,revolut,santander_przelew24,open_bank_success,open_bank_failure,open_bank_cancelled"}
adyen = { banks = "aib,bank_of_scotland,danske_bank,first_direct,first_trust,halifax,lloyds,monzo,nat_west,nationwide_bank,royal_bank_of_scotland,starling,tsb_bank,tesco_bank,ulster_bank,barclays,hsbc_bank,revolut,santander_przelew24,open_bank_success,open_bank_failure,open_bank_cancelled" }
[mandates.supported_payment_methods]
pay_later.klarna = {connector_list = "adyen"}
wallet.google_pay = {connector_list = "stripe,adyen"}
wallet.apple_pay = {connector_list = "stripe,adyen,cybersource,noon"}
wallet.paypal = {connector_list = "adyen"}
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"}
bank_debit.ach = { connector_list = "gocardless"}
bank_debit.becs = { connector_list = "gocardless"}
bank_debit.sepa = { connector_list = "gocardless"}
bank_redirect.ideal = {connector_list = "stripe,adyen,globalpay"}
bank_redirect.sofort = {connector_list = "stripe,adyen,globalpay"}
bank_redirect.giropay = {connector_list = "adyen,globalpay"}
pay_later.klarna = { connector_list = "adyen" }
wallet.google_pay = { connector_list = "stripe,adyen" }
wallet.apple_pay = { connector_list = "stripe,adyen,cybersource,noon" }
wallet.paypal = { connector_list = "adyen" }
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" }
bank_debit.ach = { connector_list = "gocardless" }
bank_debit.becs = { connector_list = "gocardless" }
bank_debit.sepa = { connector_list = "gocardless" }
bank_redirect.ideal = { connector_list = "stripe,adyen,globalpay" }
bank_redirect.sofort = { connector_list = "stripe,adyen,globalpay" }
bank_redirect.giropay = { connector_list = "adyen,globalpay" }
[mandates.update_mandate_supported]
card.credit ={connector_list ="cybersource"}
card.debit = {connector_list ="cybersource"}
card.credit = { connector_list = "cybersource" }
card.debit = { connector_list = "cybersource" }
[connector_customer]
connector_list = "gocardless,stax,stripe"
@ -389,7 +389,7 @@ redis_expiry = 900
pm_auth_key = "Some_pm_auth_key"
[lock_settings]
redis_lock_expiry_seconds = 180 # 3 * 60 seconds
redis_lock_expiry_seconds = 180 # 3 * 60 seconds
delay_between_retries_in_milliseconds = 500
[events.kafka]
@ -441,3 +441,17 @@ file_storage_backend = "file_system"
[unmasked_headers]
keys = "user-agent"
[opensearch]
host = "https://opensearch:9200"
[opensearch.auth]
auth = "basic"
username = "admin"
password = "admin"
region = "eu-central-1"
[opensearch.indexes]
payment_attempts = "hyperswitch-payment-attempt-events"
payment_intents = "hyperswitch-payment-intent-events"
refunds = "hyperswitch-refund-events"

View File

@ -1,7 +1,7 @@
[package]
name = "analytics"
version = "0.1.0"
description = "Analytics / Reports related functionality"
description = "Analytics / Reports / Search related functionality"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -9,29 +9,43 @@ edition = "2021"
[dependencies]
# First party crates
api_models = { version = "0.1.0", path = "../api_models" , features = ["errors"]}
api_models = { version = "0.1.0", path = "../api_models", features = [
"errors",
] }
storage_impl = { version = "0.1.0", path = "../storage_impl", default-features = false }
common_utils = { version = "0.1.0", path = "../common_utils" }
external_services = { version = "0.1.0", path = "../external_services", default-features = false }
hyperswitch_interfaces = { version = "0.1.0", path = "../hyperswitch_interfaces" }
masking = { version = "0.1.0", path = "../masking" }
router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"] }
diesel_models = { version = "0.1.0", path = "../diesel_models", features = ["kv_store"] }
router_env = { version = "0.1.0", path = "../router_env", features = [
"log_extra_implicit_fields",
"log_custom_entries_to_extra",
] }
diesel_models = { version = "0.1.0", path = "../diesel_models", features = [
"kv_store",
] }
#Third Party dependencies
actix-web = "4.3.1"
async-trait = "0.1.68"
aws-config = { version = "0.55.3" }
aws-sdk-lambda = { version = "0.28.0" }
aws-smithy-types = { version = "0.55.3" }
aws-config = { version = "1.1.6", features = ["behavior-version-latest"] }
aws-sdk-lambda = { version = "1.1.4" }
aws-smithy-types = { version = "1.1.6" }
bigdecimal = { version = "0.3.1", features = ["serde"] }
error-stack = "0.3.1"
futures = "0.3.28"
opensearch = { version = "2.2.0", features = ["aws-auth"] }
once_cell = "1.18.0"
reqwest = { version = "0.11.18", features = ["serde_json"] }
serde = { version = "1.0.193", features = ["derive", "rc"] }
serde_json = "1.0.108"
sqlx = { version = "0.6.3", features = ["postgres", "runtime-actix", "runtime-actix-native-tls", "time", "bigdecimal"] }
sqlx = { version = "0.6.3", features = [
"postgres",
"runtime-actix",
"runtime-actix-native-tls",
"time",
"bigdecimal",
] }
strum = { version = "0.25.0", features = ["derive"] }
thiserror = "1.0.43"
time = { version = "0.3.21", features = ["serde", "serde-well-known", "std"] }

View File

@ -1,5 +1,5 @@
use aws_config::{self, meta::region::RegionProviderChain};
use aws_sdk_lambda::{config::Region, types::InvocationType::Event, Client};
use aws_config::{self, meta::region::RegionProviderChain, Region};
use aws_sdk_lambda::{types::InvocationType::Event, Client};
use aws_smithy_types::Blob;
use common_utils::errors::CustomResult;
use error_stack::{IntoReport, ResultExt};

View File

@ -12,6 +12,7 @@ pub mod connector_events;
pub mod health_check;
pub mod outgoing_webhook_event;
pub mod sdk_events;
pub mod search;
mod sqlx;
mod types;
use api_event::metrics::{ApiEventMetric, ApiEventMetricRow};
@ -664,3 +665,42 @@ pub struct ReportConfig {
pub dispute_function: String,
pub region: String,
}
#[derive(Clone, Debug, serde::Deserialize)]
#[serde(tag = "auth")]
#[serde(rename_all = "lowercase")]
pub enum OpensearchAuth {
Basic { username: String, password: String },
Aws { region: String },
}
#[derive(Clone, Debug, serde::Deserialize)]
pub struct OpensearchIndexes {
pub payment_attempts: String,
pub payment_intents: String,
pub refunds: String,
}
#[derive(Clone, Debug, serde::Deserialize)]
pub struct OpensearchConfig {
host: String,
auth: OpensearchAuth,
indexes: OpensearchIndexes,
}
impl Default for OpensearchConfig {
fn default() -> Self {
Self {
host: "https://localhost:9200".to_string(),
auth: OpensearchAuth::Basic {
username: "admin".to_string(),
password: "admin".to_string(),
},
indexes: OpensearchIndexes {
payment_attempts: "hyperswitch-payment-attempt-events".to_string(),
payment_intents: "hyperswitch-payment-intent-events".to_string(),
refunds: "hyperswitch-refund-events".to_string(),
},
}
}
}

View File

@ -0,0 +1,150 @@
use api_models::analytics::search::{
GetGlobalSearchRequest, GetSearchRequestWithIndex, GetSearchResponse, OpenMsearchOutput,
OpensearchOutput, SearchIndex,
};
use aws_config::{self, meta::region::RegionProviderChain, Region};
use common_utils::errors::CustomResult;
use opensearch::{
auth::Credentials,
cert::CertificateValidation,
http::{
request::JsonBody,
transport::{SingleNodeConnectionPool, TransportBuilder},
Url,
},
MsearchParts, OpenSearch, SearchParts,
};
use serde_json::{json, Value};
use strum::IntoEnumIterator;
use crate::{errors::AnalyticsError, OpensearchAuth, OpensearchConfig, OpensearchIndexes};
#[derive(Debug, thiserror::Error)]
pub enum OpensearchError {
#[error("Opensearch connection error")]
ConnectionError,
#[error("Opensearch NON-200 response content: '{0}'")]
ResponseNotOK(String),
#[error("Opensearch response error")]
ResponseError,
}
pub fn search_index_to_opensearch_index(index: SearchIndex, config: &OpensearchIndexes) -> String {
match index {
SearchIndex::PaymentAttempts => config.payment_attempts.clone(),
SearchIndex::PaymentIntents => config.payment_intents.clone(),
SearchIndex::Refunds => config.refunds.clone(),
}
}
async fn get_opensearch_client(config: OpensearchConfig) -> Result<OpenSearch, OpensearchError> {
let url = Url::parse(&config.host).map_err(|_| OpensearchError::ConnectionError)?;
let transport = match config.auth {
OpensearchAuth::Basic { username, password } => {
let credentials = Credentials::Basic(username, password);
TransportBuilder::new(SingleNodeConnectionPool::new(url))
.cert_validation(CertificateValidation::None)
.auth(credentials)
.build()
.map_err(|_| OpensearchError::ConnectionError)?
}
OpensearchAuth::Aws { region } => {
let region_provider = RegionProviderChain::first_try(Region::new(region));
let sdk_config = aws_config::from_env().region(region_provider).load().await;
let conn_pool = SingleNodeConnectionPool::new(url);
TransportBuilder::new(conn_pool)
.auth(
sdk_config
.clone()
.try_into()
.map_err(|_| OpensearchError::ConnectionError)?,
)
.service_name("es")
.build()
.map_err(|_| OpensearchError::ConnectionError)?
}
};
Ok(OpenSearch::new(transport))
}
pub async fn msearch_results(
req: GetGlobalSearchRequest,
merchant_id: &String,
config: OpensearchConfig,
) -> CustomResult<Vec<GetSearchResponse>, AnalyticsError> {
let client = get_opensearch_client(config.clone())
.await
.map_err(|_| AnalyticsError::UnknownError)?;
let mut msearch_vector: Vec<JsonBody<Value>> = vec![];
for index in SearchIndex::iter() {
msearch_vector
.push(json!({"index": search_index_to_opensearch_index(index,&config.indexes)}).into());
msearch_vector.push(json!({"query": {"bool": {"must": {"query_string": {"query": req.query}}, "filter": {"match_phrase": {"merchant_id": merchant_id}}}}}).into());
}
let response = client
.msearch(MsearchParts::None)
.body(msearch_vector)
.send()
.await
.map_err(|_| AnalyticsError::UnknownError)?;
let response_body = response
.json::<OpenMsearchOutput<Value>>()
.await
.map_err(|_| AnalyticsError::UnknownError)?;
Ok(response_body
.responses
.into_iter()
.zip(SearchIndex::iter())
.map(|(index_hit, index)| GetSearchResponse {
count: index_hit.hits.total.value,
index,
hits: index_hit
.hits
.hits
.into_iter()
.map(|hit| hit._source)
.collect(),
})
.collect())
}
pub async fn search_results(
req: GetSearchRequestWithIndex,
merchant_id: &String,
config: OpensearchConfig,
) -> CustomResult<GetSearchResponse, AnalyticsError> {
let search_req = req.search_req;
let client = get_opensearch_client(config.clone())
.await
.map_err(|_| AnalyticsError::UnknownError)?;
let response = client
.search(SearchParts::Index(&[&search_index_to_opensearch_index(req.index.clone(),&config.indexes)]))
.from(search_req.offset)
.size(search_req.count)
.body(json!({"query": {"bool": {"must": {"query_string": {"query": search_req.query}}, "filter": {"match_phrase": {"merchant_id": merchant_id}}}}}))
.send()
.await
.map_err(|_| AnalyticsError::UnknownError)?;
let response_body = response
.json::<OpensearchOutput<Value>>()
.await
.map_err(|_| AnalyticsError::UnknownError)?;
Ok(GetSearchResponse {
count: response_body.hits.total.value,
index: req.index,
hits: response_body
.hits
.hits
.into_iter()
.map(|hit| hit._source)
.collect(),
})
}

View File

@ -19,6 +19,7 @@ pub mod outgoing_webhook_event;
pub mod payments;
pub mod refunds;
pub mod sdk_events;
pub mod search;
#[derive(Debug, serde::Serialize)]
pub struct NameDescription {
@ -251,7 +252,6 @@ pub struct GetApiEventMetricRequest {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetDisputeFilterRequest {
pub time_range: TimeRange,
#[serde(default)]

View File

@ -0,0 +1,73 @@
use serde_json::Value;
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
pub struct SearchFilters {
pub payment_method: Option<Vec<String>>,
}
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetGlobalSearchRequest {
pub query: String,
#[serde(default)]
pub filters: Option<SearchFilters>,
}
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetSearchRequest {
pub offset: i64,
pub count: i64,
pub query: String,
#[serde(default)]
pub filters: Option<SearchFilters>,
}
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetSearchRequestWithIndex {
pub index: SearchIndex,
pub search_req: GetSearchRequest,
}
#[derive(Debug, strum::EnumIter, Clone, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum SearchIndex {
PaymentAttempts,
PaymentIntents,
Refunds,
}
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetSearchResponse {
pub count: u64,
pub index: SearchIndex,
pub hits: Vec<Value>,
}
#[derive(Debug, serde::Deserialize)]
pub struct OpenMsearchOutput<T> {
pub responses: Vec<OpensearchOutput<T>>,
}
#[derive(Debug, serde::Deserialize)]
pub struct OpensearchOutput<T> {
pub hits: OpensearchResults<T>,
}
#[derive(Debug, serde::Deserialize)]
pub struct OpensearchResults<T> {
pub total: OpensearchResultsTotal,
pub hits: Vec<OpensearchHits<T>>,
}
#[derive(Debug, serde::Deserialize)]
pub struct OpensearchResultsTotal {
pub value: u64,
}
#[derive(Debug, serde::Deserialize)]
pub struct OpensearchHits<T> {
pub _source: T,
}

View File

@ -23,7 +23,7 @@ use crate::{
admin::*,
analytics::{
api_event::*, connector_events::ConnectorEventsRequest,
outgoing_webhook_event::OutgoingWebhookLogsRequest, sdk_events::*, *,
outgoing_webhook_event::OutgoingWebhookLogsRequest, sdk_events::*, search::*, *,
},
api_keys::*,
cards_info::*,
@ -96,6 +96,10 @@ impl_misc_api_event_type!(
ReportRequest,
ConnectorEventsRequest,
OutgoingWebhookLogsRequest,
GetGlobalSearchRequest,
GetSearchRequest,
GetSearchResponse,
GetSearchRequestWithIndex,
GetDisputeFilterRequest,
DisputeFiltersResponse,
GetDisputeMetricRequest

View File

@ -8,6 +8,9 @@ pub mod routes {
outgoing_webhook_event::outgoing_webhook_events_core, sdk_events::sdk_events_core,
};
use api_models::analytics::{
search::{
GetGlobalSearchRequest, GetSearchRequest, GetSearchRequestWithIndex, SearchIndex,
},
GenerateReportRequest, GetApiEventFiltersRequest, GetApiEventMetricRequest,
GetDisputeMetricRequest, GetPaymentFiltersRequest, GetPaymentMetricRequest,
GetRefundFilterRequest, GetRefundMetricRequest, GetSdkEventFiltersRequest,
@ -89,6 +92,12 @@ pub mod routes {
web::resource("metrics/api_events")
.route(web::post().to(get_api_events_metrics)),
)
.service(
web::resource("search").route(web::post().to(get_global_search_results)),
)
.service(
web::resource("search/{domain}").route(web::post().to(get_search_results)),
)
.service(
web::resource("filters/disputes")
.route(web::post().to(get_dispute_filters)),
@ -113,7 +122,7 @@ pub mod routes {
state,
&req,
domain.into_inner(),
|_, _, domain| async {
|_, _, domain: analytics::AnalyticsDomain| async {
analytics::core::get_domain_info(domain)
.await
.map(ApplicationResponse::Json)
@ -592,6 +601,63 @@ pub mod routes {
.await
}
pub async fn get_global_search_results(
state: web::Data<AppState>,
req: actix_web::HttpRequest,
json_payload: web::Json<GetGlobalSearchRequest>,
) -> impl Responder {
let flow = AnalyticsFlow::GetGlobalSearchResults;
Box::pin(api::server_wrap(
flow,
state.clone(),
&req,
json_payload.into_inner(),
|state, auth: AuthenticationData, req| async move {
analytics::search::msearch_results(
req,
&auth.merchant_account.merchant_id,
state.conf.opensearch.clone(),
)
.await
.map(ApplicationResponse::Json)
},
&auth::JWTAuth(Permission::Analytics),
api_locking::LockAction::NotApplicable,
))
.await
}
pub async fn get_search_results(
state: web::Data<AppState>,
req: actix_web::HttpRequest,
json_payload: web::Json<GetSearchRequest>,
index: actix_web::web::Path<SearchIndex>,
) -> impl Responder {
let flow = AnalyticsFlow::GetSearchResults;
let indexed_req = GetSearchRequestWithIndex {
search_req: json_payload.into_inner(),
index: index.into_inner(),
};
Box::pin(api::server_wrap(
flow,
state.clone(),
&req,
indexed_req,
|state, auth: AuthenticationData, req| async move {
analytics::search::search_results(
req,
&auth.merchant_account.merchant_id,
state.conf.opensearch.clone(),
)
.await
.map(ApplicationResponse::Json)
},
&auth::JWTAuth(Permission::Analytics),
api_locking::LockAction::NotApplicable,
))
.await
}
pub async fn get_dispute_filters(
state: web::Data<AppState>,
req: actix_web::HttpRequest,

View File

@ -350,6 +350,8 @@ pub(crate) async fn fetch_raw_secrets(
payment_link: conf.payment_link,
#[cfg(feature = "olap")]
analytics,
#[cfg(feature = "olap")]
opensearch: conf.opensearch,
#[cfg(feature = "kv_store")]
kv_config: conf.kv_config,
#[cfg(feature = "frm")]

View File

@ -4,7 +4,7 @@ use std::{
};
#[cfg(feature = "olap")]
use analytics::ReportConfig;
use analytics::{OpensearchConfig, ReportConfig};
use api_models::{enums, payment_methods::RequiredFieldInfo};
use common_utils::ext_traits::ConfigExt;
use config::{Environment, File};
@ -112,6 +112,8 @@ pub struct Settings<S: SecretState> {
pub frm: Frm,
#[cfg(feature = "olap")]
pub report_download_config: ReportConfig,
#[cfg(feature = "olap")]
pub opensearch: OpensearchConfig,
pub events: EventsConfig,
#[cfg(feature = "olap")]
pub connector_onboarding: SecretStateContainer<ConnectorOnboarding, S>,

View File

@ -54,6 +54,8 @@ pub enum AnalyticsFlow {
GetApiEventFilters,
GetConnectorEvents,
GetOutgoingWebhookEvents,
GetGlobalSearchResults,
GetSearchResults,
GetDisputeFilters,
GetDisputeMetrics,
}