Skip to content

Commit

Permalink
Support Braintree subaccounts (#9191)
Browse files Browse the repository at this point in the history
This adds a new optional field to the plugin configuration screen. If
set, it will override the default merchant account used for
transactions.

Refunds and viods automatically use the merchant account that the
original transaction used so they don't pass the override.
  • Loading branch information
patrys committed Mar 1, 2022
1 parent 2b741db commit 035bf70
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 12 deletions.
2 changes: 1 addition & 1 deletion saleor/payment/gateways/adyen/plugin.py
Expand Up @@ -83,7 +83,7 @@ class AdyenGatewayPlugin(BasePlugin):
},
"merchant-account": {
"type": ConfigurationTypeField.STRING,
"help_text": "Yout merchant account name.",
"help_text": "Your merchant account name.",
"label": "Merchant Account",
},
"supported-currencies": {
Expand Down
16 changes: 13 additions & 3 deletions saleor/payment/gateways/braintree/__init__.py
Expand Up @@ -88,7 +88,9 @@ def extract_gateway_response(braintree_result) -> Dict:
}


def get_braintree_gateway(sandbox_mode, merchant_id, public_key, private_key):
def get_braintree_gateway(
sandbox_mode, merchant_id, public_key, private_key, merchant_account_id
):
if not all([merchant_id, private_key, public_key]):
raise ImproperlyConfigured("Incorrectly configured Braintree gateway.")
environment = braintree_sdk.Environment.Sandbox
Expand Down Expand Up @@ -181,6 +183,10 @@ def transaction_for_new_customer(
span = scope.span
span.set_tag(opentracing.tags.COMPONENT, "payment")
span.set_tag("service.name", "braintree")
params = get_customer_data(payment_information)
merchant_account_id = config.connection_params["merchant_account_id"]
if merchant_account_id:
params["merchant_account_id"] = merchant_account_id
return gateway.transaction.sale(
{
"amount": str(payment_information.amount),
Expand All @@ -190,7 +196,7 @@ def transaction_for_new_customer(
"store_in_vault_on_success": payment_information.reuse_source,
"three_d_secure": {"required": config.require_3d_secure},
},
**get_customer_data(payment_information),
**params,
}
)

Expand All @@ -205,12 +211,16 @@ def transaction_for_existing_customer(
span = scope.span
span.set_tag(opentracing.tags.COMPONENT, "payment")
span.set_tag("service.name", "braintree")
params = get_customer_data(payment_information)
merchant_account_id = config.connection_params["merchant_account_id"]
if merchant_account_id:
params["merchant_account_id"] = merchant_account_id
return gateway.transaction.sale(
{
"amount": str(payment_information.amount),
"customer_id": payment_information.customer_id,
"options": {"submit_for_settlement": config.auto_capture},
**get_customer_data(payment_information),
**params,
}
)

Expand Down
23 changes: 15 additions & 8 deletions saleor/payment/gateways/braintree/plugin.py
Expand Up @@ -32,6 +32,7 @@ class BraintreeGatewayPlugin(BasePlugin):
{"name": "Secret API key", "value": None},
{"name": "Use sandbox", "value": True},
{"name": "Merchant ID", "value": None},
{"name": "Merchant Account ID", "value": None},
{"name": "Store customers card", "value": False},
{"name": "Automatic payment capture", "value": True},
{"name": "Require 3D secure", "value": False},
Expand All @@ -42,28 +43,33 @@ class BraintreeGatewayPlugin(BasePlugin):
"Public API key": {
"type": ConfigurationTypeField.SECRET,
"help_text": "Provide Braintree public API key.",
"label": "Public API key",
"label": "Public Key",
},
"Secret API key": {
"type": ConfigurationTypeField.SECRET,
"help_text": "Provide Braintree secret API key.",
"label": "Secret API key",
"help_text": "Provide Braintree private API key.",
"label": "Private Key",
},
"Merchant ID": {
"type": ConfigurationTypeField.SECRET,
"type": ConfigurationTypeField.STRING,
"help_text": "Provide Braintree merchant ID.",
"label": "Merchant ID",
},
"Merchant Account ID": {
"type": ConfigurationTypeField.STRING,
"help_text": "Optional. If empty, the default account will be used.",
"label": "Merchant Account ID",
},
"Use sandbox": {
"type": ConfigurationTypeField.BOOLEAN,
"help_text": "Determines if Saleor should use Braintree sandbox API.",
"label": "Use sandbox",
"label": "Sandbox mode",
},
"Store customers card": {
"type": ConfigurationTypeField.BOOLEAN,
"help_text": "Determines if Saleor should store cards on payments"
" in Braintree customer.",
"label": "Store customers card",
"label": "Store customer cards",
},
"Automatic payment capture": {
"type": ConfigurationTypeField.BOOLEAN,
Expand All @@ -72,8 +78,8 @@ class BraintreeGatewayPlugin(BasePlugin):
},
"Require 3D secure": {
"type": ConfigurationTypeField.BOOLEAN,
"help_text": "Determines if Saleor should enforce 3D secure during payment.",
"label": "Require 3D secure",
"help_text": "Determines if Saleor should enforce 3D Secure during payment.",
"label": "Require 3D Secure",
},
"Supported currencies": {
"type": ConfigurationTypeField.STRING,
Expand All @@ -93,6 +99,7 @@ def __init__(self, *args, **kwargs):
connection_params={
"sandbox_mode": configuration["Use sandbox"],
"merchant_id": configuration["Merchant ID"],
"merchant_account_id": configuration["Merchant Account ID"],
"public_key": configuration["Public API key"],
"private_key": configuration["Secret API key"],
},
Expand Down
2 changes: 2 additions & 0 deletions saleor/payment/gateways/braintree/tests/test_braintree.py
Expand Up @@ -84,6 +84,7 @@ def gateway_config():
"merchant_id": "123",
"public_key": "456",
"private_key": "789",
"merchant_account_id": "",
},
supported_currencies="USD",
)
Expand Down Expand Up @@ -255,6 +256,7 @@ def sandbox_braintree_gateway_config(gateway_config):
"public_key": "fake_public_key", # CHANGE WHEN RECORDING
"private_key": "fake_private_key", # CHANGE WHEN RECORDING
"sandbox_mode": True,
"merchant_account_id": "",
}
gateway_config.auto_capture = True
return gateway_config
Expand Down

0 comments on commit 035bf70

Please sign in to comment.