-
Notifications
You must be signed in to change notification settings - Fork 4.2k
feat(connector): Add recovery support for stripebilling #7461
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
Merged
likhinbopanna
merged 122 commits into
main
from
billing_connector_additional_api_call_flow
Apr 2, 2025
Merged
Changes from 112 commits
Commits
Show all changes
122 commits
Select commit
Hold shift + click to select a range
a0ffaa7
add template code for stripebilling
bb432a5
add logic instead of todo in template code
4555023
chore: run formatter
hyperswitch-bot[bot] 8ab0630
Merge branch 'main' into template_code_stripebilling
2ad25d7
fixes errors
3c38093
chore: run formatter
hyperswitch-bot[bot] a2ca88b
Merge branch 'main' into template_code_stripebilling
NISHANTH1221 4412b10
resolved error in default implementation
d6c7f7a
additional api call flow for revenue recovery
0139e03
Merge branch 'main' into template_code_stripebilling
ccfcff3
chore: run formatter
hyperswitch-bot[bot] 4abdce9
Merge branch 'main' into template_code_stripebilling
NISHANTH1221 6e08413
Merge branch 'main' into template_code_stripebilling
NISHANTH1221 edbe0bd
add incoming webhook support and recovery invoice flow
3295979
chore: run formatter
hyperswitch-bot[bot] 0d5a8ea
changes in name of the flow in config files
1ad2464
chore: run formatter
hyperswitch-bot[bot] 24dd8cf
cargo.toml changes in par with main
70b7546
Merge branch 'template_code_stripebilling' into additional_recovery_c…
NISHANTH1221 966ce1b
add paystack in deafult implememtation additional call flow
6f4573a
Merge branch 'main' into additional_recovery_call_flow
NISHANTH1221 4a34e07
added paystack connector in default implementation
e10b589
add debug and clone trait to Additional Revenue Recovery Flow Common …
145a6d9
chore: run formatter
hyperswitch-bot[bot] 2cc26be
resolve spell check
70a430f
add stripebilling in configs
c9ae685
refactor: rename Additional Revenue Recovery related types and traits
65326ec
Merge branch 'main' into stripebilling_incoming_webhook_support
524cce1
chore: run formatter
hyperswitch-bot[bot] 66132cb
refactor: reorganize revenue recovery module structure
f2d5295
Merge branch 'additional_recovery_call_flow' into stripebilling_incom…
fc01f6c
chore: run formatter
hyperswitch-bot[bot] f93bbc6
Merge branch 'main' into additional_recovery_call_flow
NISHANTH1221 cec5702
Merge branch 'additional_recovery_call_flow' into stripebilling_incom…
51e6dcd
change v2 to v1
2cd73be
chore: run formatter
hyperswitch-bot[bot] e5b8314
refactor: update additional revenue recovery call implementations for…
eaaa438
Merge branch 'additional_recovery_call_flow' into stripebilling_incom…
NISHANTH1221 25855cc
refactor: add RevenueRecovery trait and update related implementations
ad1e7dd
chore: run formatter
hyperswitch-bot[bot] 7c05cb5
refactor: update revenue recovery request data structure
8cd127d
refactor: add necessary changes for connector to be enabled and reolv…
80ac277
removed unnecessary comments
738c251
chore: run formatter
hyperswitch-bot[bot] 66e85bc
Merge branch 'additional_recovery_call_flow' into stripebilling_incom…
f09f19c
Merge branch 'main' into additional_recovery_call_flow
NISHANTH1221 968ba54
feat: Add Stripebilling revenue recovery support and additional detai…
5bf5bf1
feat(connector): add Recurly to additional revenue recovery call
43275b8
Merge branch 'additional_recovery_call_flow' into stripebilling_incom…
21d47f2
Merge branch 'stripebilling_incoming_webhook_support' into billing_co…
2e38d3b
Merge branch 'main' into stripebilling_incoming_webhook_support
NISHANTH1221 11f4ae4
feat(connector): Enable Stripebilling webhook support with additional…
44cf2c4
chore: run formatter
hyperswitch-bot[bot] ec4aa43
Switch default feature from v2 to v1
2a0965b
Merge branch 'main' into stripebilling_incoming_webhook_support
NISHANTH1221 c3aca3a
Merge branch 'main' into stripebilling_incoming_webhook_support
NISHANTH1221 48395a4
Merge branch 'stripebilling_incoming_webhook_support' into billing_co…
b1a2f3a
Adds Hipay and Juspaythreedsserver to revenue recovery flow
8c5f05d
chore: run formatter
hyperswitch-bot[bot] 0e8966c
Merge branch 'main' into stripebilling_incoming_webhook_support
NISHANTH1221 1598eeb
Merge branch 'main' into stripebilling_incoming_webhook_support
NISHANTH1221 a8a9777
Merge branch 'stripebilling_incoming_webhook_support' into billing_co…
NISHANTH1221 55347ff
resolve stripebilling payment mca issue
5f21920
Merge branch 'main' into stripebilling_incoming_webhook_support
c234e27
resolve spell check
74451f8
Merge branch 'main' into stripebilling_incoming_webhook_support
NISHANTH1221 9fe1b4e
refactor hanging functions in recoevry_incoming
663bb0d
spell check resolve
ff80f84
spell check resolve
ac5e0cb
Merge branch 'main' into stripebilling_incoming_webhook_support
NISHANTH1221 f5629b7
Merge branch 'stripebilling_incoming_webhook_support' into billing_co…
398c61e
chore: run formatter
hyperswitch-bot[bot] 2f7d5af
feat(revenue_recovery): derive Debug and Clone for GetAdditionalReven…
d1f79e2
chore: run formatter
hyperswitch-bot[bot] be2855b
solved the errors in the flow
439da0b
chore: run formatter
hyperswitch-bot[bot] a76bfe5
Merge branch 'main' into stripebilling_incoming_webhook_support
NISHANTH1221 0d4b48f
Merge branch 'stripebilling_incoming_webhook_support' into billing_co…
c86fb35
chore: run formatter
hyperswitch-bot[bot] c98e0e4
Merge branch 'main' into stripebilling_incoming_webhook_support
NISHANTH1221 9c330c4
refactor: update failure_code and failure_message to be optional; rem…
299c68b
Merge branch 'stripebilling_incoming_webhook_support' into billing_co…
NISHANTH1221 effae0b
chore: run formatter
hyperswitch-bot[bot] 77bb4bf
remove print statements
0654060
chore: run formatter
hyperswitch-bot[bot] 0aaed17
Merge branch 'main' into billing_connector_additional_api_call_flow
ab5a21e
chore: run formatter
hyperswitch-bot[bot] 0e53ec7
resolve merge errors
10034e2
chore: run formatter
hyperswitch-bot[bot] 97eaa8f
Merge branch 'main' into billing_connector_additional_api_call_flow
ad85e5f
chore: run formatter
hyperswitch-bot[bot] b947288
resolve clippy errors
7ba0527
Simplify webhook event handling and improve data cloning in revenue r…
64d00ed
remove print statement
7f6dd29
refactor match statments
7ef279f
format code
8e5b5f1
refactor object reference id tuple implementation to object reference…
b0738ec
Merge branch 'main' into billing_connector_additional_api_call_flow
NISHANTH1221 8ae6fb7
docs(openapi): re-generate OpenAPI specification
hyperswitch-bot[bot] ec69c03
Merge branch 'main' into billing_connector_additional_api_call_flow
aniketburman014 640c690
reduced match statements
ca92111
chore: run formatter
hyperswitch-bot[bot] 3da0b3d
specific import resolve
404d5fb
use router data v2 and converts it into v1 while calling
d4a64e2
chore: run formatter
hyperswitch-bot[bot] bb63b04
refactor minor changes
756edcb
formatter
c771b3e
Merge branch 'main' into billing_connector_additional_api_call_flow
2b14293
format code
8a107d8
handle other additional revenue recovery id types
0b15b29
Merge branch 'main' into billing_connector_additional_api_call_flow
NISHANTH1221 59fd066
remove unnecesssary comment
76ca75b
refactor(webhooks): remove AdditionalRevenueRecoveryId and update rel…
95a77d7
Merge branch 'main' into billing_connector_additional_api_call_flow
b391c2d
chore: run formatter
hyperswitch-bot[bot] 38678ce
resolve conficts
cd846e1
change additional revenue recovery to billing conenctor payment sync
7006f1d
chore: run formatter
hyperswitch-bot[bot] 8364cb1
comment change
2ef938d
Merge branch 'main' into billing_connector_additional_api_call_flow
dfe7a20
resolve merge conflicts
bd578f2
spell check resolve
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -9,6 +9,8 @@ use common_utils::{ | |||||
types::{AmountConvertor, StringMinorUnit, StringMinorUnitForConnector}, | ||||||
}; | ||||||
use error_stack::{report, ResultExt}; | ||||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))] | ||||||
use hyperswitch_domain_models::revenue_recovery; | ||||||
use hyperswitch_domain_models::{ | ||||||
router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData}, | ||||||
router_flow_types::{ | ||||||
|
@@ -29,10 +31,16 @@ use hyperswitch_domain_models::{ | |||||
}; | ||||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))] | ||||||
use hyperswitch_domain_models::{ | ||||||
router_flow_types::RecoveryRecordBack, | ||||||
router_request_types::revenue_recovery::RevenueRecoveryRecordBackRequest, | ||||||
router_response_types::revenue_recovery::RevenueRecoveryRecordBackResponse, | ||||||
types::RevenueRecoveryRecordBackRouterData, | ||||||
router_flow_types::revenue_recovery::{ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
GetAdditionalRevenueRecoveryDetails, RecoveryRecordBack, | ||||||
}, | ||||||
router_request_types::revenue_recovery::{ | ||||||
GetAdditionalRevenueRecoveryRequestData, RevenueRecoveryRecordBackRequest, | ||||||
}, | ||||||
router_response_types::revenue_recovery::{ | ||||||
GetAdditionalRevenueRecoveryResponseData, RevenueRecoveryRecordBackResponse, | ||||||
}, | ||||||
types::{AdditionalRevenueRecoveryDetailsRouterData, RevenueRecoveryRecordBackRouterData}, | ||||||
}; | ||||||
use hyperswitch_interfaces::{ | ||||||
api::{ | ||||||
|
@@ -45,7 +53,10 @@ use hyperswitch_interfaces::{ | |||||
types::{self, Response}, | ||||||
webhooks, | ||||||
}; | ||||||
use masking::{ExposeInterface, Mask}; | ||||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))] | ||||||
use masking::ExposeInterface; | ||||||
use masking::{Mask, PeekInterface}; | ||||||
use stripebilling::auth_headers; | ||||||
use transformers as stripebilling; | ||||||
|
||||||
use crate::{constants::headers, types::ResponseRouterData, utils}; | ||||||
|
@@ -77,6 +88,8 @@ impl api::RefundSync for Stripebilling {} | |||||
impl api::PaymentToken for Stripebilling {} | ||||||
#[cfg(all(feature = "revenue_recovery", feature = "v2"))] | ||||||
impl api::revenue_recovery::RevenueRecoveryRecordBack for Stripebilling {} | ||||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))] | ||||||
impl api::AdditionalRevenueRecovery for Stripebilling {} | ||||||
|
||||||
impl ConnectorIntegration<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData> | ||||||
for Stripebilling | ||||||
|
@@ -126,10 +139,16 @@ impl ConnectorCommon for Stripebilling { | |||||
) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> { | ||||||
let auth = stripebilling::StripebillingAuthType::try_from(auth_type) | ||||||
.change_context(errors::ConnectorError::FailedToObtainAuthType)?; | ||||||
Ok(vec![( | ||||||
headers::AUTHORIZATION.to_string(), | ||||||
auth.api_key.expose().into_masked(), | ||||||
)]) | ||||||
Ok(vec![ | ||||||
( | ||||||
headers::AUTHORIZATION.to_string(), | ||||||
format!("Bearer {}", auth.api_key.peek()).into_masked(), | ||||||
), | ||||||
( | ||||||
auth_headers::STRIPE_API_VERSION.to_string(), | ||||||
auth_headers::STRIPE_VERSION.to_string().into_masked(), | ||||||
), | ||||||
]) | ||||||
} | ||||||
|
||||||
fn build_error_response( | ||||||
|
@@ -559,6 +578,88 @@ impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Stripebil | |||||
} | ||||||
} | ||||||
|
||||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))] | ||||||
impl | ||||||
ConnectorIntegration< | ||||||
GetAdditionalRevenueRecoveryDetails, | ||||||
GetAdditionalRevenueRecoveryRequestData, | ||||||
GetAdditionalRevenueRecoveryResponseData, | ||||||
> for Stripebilling | ||||||
{ | ||||||
fn get_headers( | ||||||
&self, | ||||||
req: &AdditionalRevenueRecoveryDetailsRouterData, | ||||||
connectors: &Connectors, | ||||||
) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> { | ||||||
self.build_headers(req, connectors) | ||||||
} | ||||||
|
||||||
fn get_content_type(&self) -> &'static str { | ||||||
self.common_get_content_type() | ||||||
} | ||||||
|
||||||
fn get_url( | ||||||
&self, | ||||||
req: &AdditionalRevenueRecoveryDetailsRouterData, | ||||||
connectors: &Connectors, | ||||||
) -> CustomResult<String, errors::ConnectorError> { | ||||||
Ok(format!( | ||||||
"{}v1/charges/{}", | ||||||
self.base_url(connectors), | ||||||
req.request.additional_revenue_recovery_id | ||||||
)) | ||||||
} | ||||||
|
||||||
fn build_request( | ||||||
&self, | ||||||
req: &AdditionalRevenueRecoveryDetailsRouterData, | ||||||
connectors: &Connectors, | ||||||
) -> CustomResult<Option<Request>, errors::ConnectorError> { | ||||||
let request = RequestBuilder::new() | ||||||
.method(Method::Get) | ||||||
.url(&types::AdditionalRevenueRecoveryCallType::get_url( | ||||||
self, req, connectors, | ||||||
)?) | ||||||
.attach_default_headers() | ||||||
.headers(types::AdditionalRevenueRecoveryCallType::get_headers( | ||||||
self, req, connectors, | ||||||
)?) | ||||||
.build(); | ||||||
Ok(Some(request)) | ||||||
} | ||||||
|
||||||
fn handle_response( | ||||||
&self, | ||||||
data: &AdditionalRevenueRecoveryDetailsRouterData, | ||||||
event_builder: Option<&mut ConnectorEvent>, | ||||||
res: Response, | ||||||
) -> CustomResult<AdditionalRevenueRecoveryDetailsRouterData, errors::ConnectorError> { | ||||||
let response: stripebilling::StripebillingRecoveryDetailsData = res | ||||||
.response | ||||||
.parse_struct::<stripebilling::StripebillingRecoveryDetailsData>( | ||||||
"StripebillingRecoveryDetailsData", | ||||||
) | ||||||
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?; | ||||||
|
||||||
event_builder.map(|i| i.set_response_body(&response)); | ||||||
router_env::logger::info!(connector_response=?response); | ||||||
|
||||||
AdditionalRevenueRecoveryDetailsRouterData::try_from(ResponseRouterData { | ||||||
response, | ||||||
data: data.clone(), | ||||||
http_code: res.status_code, | ||||||
}) | ||||||
} | ||||||
|
||||||
fn get_error_response( | ||||||
&self, | ||||||
res: Response, | ||||||
event_builder: Option<&mut ConnectorEvent>, | ||||||
) -> CustomResult<ErrorResponse, errors::ConnectorError> { | ||||||
self.build_error_response(res, event_builder) | ||||||
} | ||||||
} | ||||||
|
||||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))] | ||||||
impl | ||||||
ConnectorIntegration< | ||||||
|
@@ -700,8 +801,8 @@ impl webhooks::IncomingWebhook for Stripebilling { | |||||
let webhook = | ||||||
stripebilling::StripebillingWebhookBody::get_webhook_object_from_body(request.body) | ||||||
.change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?; | ||||||
Ok(api_models::webhooks::ObjectReferenceId::PaymentId( | ||||||
api_models::payments::PaymentIdType::ConnectorTransactionId(webhook.data.object.charge), | ||||||
Ok(api_models::webhooks::ObjectReferenceId::AdditionalRevenueRecoveryId( | ||||||
api_models::webhooks::AdditionalRevenueRecoveryIdType::AdditionalRevenueRecoveryCallId(webhook.data.object.charge), | ||||||
)) | ||||||
} | ||||||
|
||||||
|
@@ -712,6 +813,7 @@ impl webhooks::IncomingWebhook for Stripebilling { | |||||
) -> CustomResult<api_models::webhooks::ObjectReferenceId, errors::ConnectorError> { | ||||||
Err(report!(errors::ConnectorError::WebhooksNotImplemented)) | ||||||
} | ||||||
|
||||||
#[cfg(all(feature = "revenue_recovery", feature = "v2"))] | ||||||
fn get_webhook_event_type( | ||||||
&self, | ||||||
|
@@ -762,6 +864,25 @@ impl webhooks::IncomingWebhook for Stripebilling { | |||||
.change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; | ||||||
Ok(Box::new(webhook)) | ||||||
} | ||||||
|
||||||
#[cfg(all(feature = "revenue_recovery", feature = "v2"))] | ||||||
fn get_revenue_recovery_attempt_details( | ||||||
&self, | ||||||
_request: &webhooks::IncomingWebhookRequestDetails<'_>, | ||||||
) -> CustomResult<revenue_recovery::RevenueRecoveryAttemptData, errors::ConnectorError> { | ||||||
// since stripe requires an additional call we dont need to implement this function because we get the recovery data from additional call itself | ||||||
Err(report!(errors::ConnectorError::WebhooksNotImplemented)) | ||||||
} | ||||||
#[cfg(all(feature = "revenue_recovery", feature = "v2"))] | ||||||
fn get_revenue_recovery_invoice_details( | ||||||
&self, | ||||||
request: &webhooks::IncomingWebhookRequestDetails<'_>, | ||||||
) -> CustomResult<revenue_recovery::RevenueRecoveryInvoiceData, errors::ConnectorError> { | ||||||
let webhook = stripebilling::StripebillingInvoiceBody::get_invoice_webhook_data_from_body( | ||||||
request.body, | ||||||
)?; | ||||||
revenue_recovery::RevenueRecoveryInvoiceData::try_from(webhook) | ||||||
} | ||||||
} | ||||||
|
||||||
fn get_signature_elements_from_header( | ||||||
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this is
AdditionalRevenueRecoveryId
ratherRevenueRecoveryId
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wanted to specify what that Id is for So named it after Additional