Skip to content

Commit 7d9bf8a

Browse files
braintreepsDavid Johnson
andcommitted
4.39.0
Co-authored-by: David Johnson <[email protected]>
1 parent fce1e1a commit 7d9bf8a

30 files changed

+974
-18
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: Security
2+
3+
on:
4+
pull_request:
5+
branches: [ master ]
6+
workflow_dispatch:
7+
8+
jobs:
9+
dependency-review:
10+
uses: PayPal-Braintree/security-workflows/.github/workflows/dependency-review.yml@main

CHANGELOG.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog
22

3+
## Unreleased
4+
* Add Bank Account Instant Verification functionality
5+
* Add `BankAccountInstantVerificationGateway` for creating JWTs
6+
* Add `BankAccountInstantVerificationJwt` response object
7+
* Add `BankAccountInstantVerificationJwtRequest` for JWT creation
8+
* Add `ach_mandate_text` and `ach_mandate_accepted_at` fields to `TransactionUsBankAccountRequest`
9+
* Add `INSTANT_VERIFICATION_ACCOUNT_VALIDATION` method to `UsBankAccountVerification.VerificationMethod`
10+
* Add support for US bank account ACH mandate fields in transaction requests
11+
* Add `ach_reject_reason` field to Transaction
12+
* Add `sender` and `receiver` to `transfer` in `Transaction`
13+
* Add `is_device_token` to ApplePayCard and ApplePayDetails
14+
315
## 4.38.0
416
* Add `upcoming_retry_date` field to Transaction
517
* Add `remaining_file_evidence_storage` to Dispute
@@ -20,7 +32,7 @@
2032
* Add business, consumer, corporate, purchase from bin data in credit card responses
2133

2234
## 4.35.0
23-
* Add support for capturing payment facilitator and sub-merchant details with transactions
35+
* Add support for capturing payment facilitator and sub-merchant details with transactions
2436
* Remove marketplace features
2537

2638
## 4.34.0
@@ -34,11 +46,11 @@
3446
* Add support for creating and updating PayPal customer session
3547
* Add support for getting PayPal customer recommendations
3648

37-
## 4.32.0
38-
* Add recipient/contact info: `recipient_email`and `recipient_phone` to `Transaction`
49+
## 4.32.0
50+
* Add recipient/contact info: `recipient_email`and `recipient_phone` to `Transaction`
3951

4052
## 4.31.0
41-
* Add `fail_on_duplicate_payment_method_for_customer` option to
53+
* Add `fail_on_duplicate_payment_method_for_customer` option to
4254
* `ClientToken`
4355
* `PaymentMethod`
4456
* `CreditCard`
@@ -98,14 +110,14 @@
98110
* Fix unittest compatibility with Python 3.12 (Thanks @mgorny)
99111

100112
## 4.23.0
101-
* Deprecate `evidenceSubmittable` in Dispute
113+
* Deprecate `evidenceSubmittable` in Dispute
102114
* Add missing `escape` calls in `generator` for:
103115
* list
104116
* bool
105117
* integer
106118
* datetime
107119

108-
## 4.22.0
120+
## 4.22.0
109121
* Add `processing_overrides` to `Transaction.sale` options
110122

111123
## 4.21.0

braintree/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
from braintree.android_pay_card import AndroidPayCard
88
from braintree.apple_pay_card import ApplePayCard
99
from braintree.apple_pay_gateway import ApplePayGateway
10+
from braintree.bank_account_instant_verification_gateway import BankAccountInstantVerificationGateway
11+
from braintree.bank_account_instant_verification_jwt import BankAccountInstantVerificationJwt
12+
from braintree.bank_account_instant_verification_jwt_request import BankAccountInstantVerificationJwtRequest
1013
from braintree.blik_alias import BlikAlias
1114
from braintree.braintree_gateway import BraintreeGateway
1215
from braintree.client_token import ClientToken
@@ -56,10 +59,12 @@
5659
from braintree.plan import Plan
5760
from braintree.plan_gateway import PlanGateway
5861
from braintree.processor_response_types import ProcessorResponseTypes
62+
from braintree.receiver import Receiver
5963
from braintree.resource_collection import ResourceCollection
6064
from braintree.risk_data import RiskData
6165
from braintree.samsung_pay_card import SamsungPayCard
6266
from braintree.search import Search
67+
from braintree.sender import Sender
6368
from braintree.sepa_direct_debit_account import SepaDirectDebitAccount
6469
from braintree.settlement_batch_summary import SettlementBatchSummary
6570
from braintree.signature_service import SignatureService
@@ -78,9 +83,11 @@
7883
from braintree.transaction_gateway import TransactionGateway
7984
from braintree.transaction_line_item import TransactionLineItem
8085
from braintree.transaction_search import TransactionSearch
86+
from braintree.transaction_us_bank_account_request import TransactionUsBankAccountRequest
8187
from braintree.transfer import Transfer
8288
from braintree.unknown_payment_method import UnknownPaymentMethod
8389
from braintree.us_bank_account import UsBankAccount
90+
from braintree.us_bank_account_verification import UsBankAccountVerification
8491
from braintree.validation_error_collection import ValidationErrorCollection
8592
from braintree.venmo_account import VenmoAccount
8693
from braintree.venmo_profile_data import VenmoProfileData
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from braintree.bank_account_instant_verification_jwt import BankAccountInstantVerificationJwt
2+
from braintree.successful_result import SuccessfulResult
3+
from braintree.error_result import ErrorResult
4+
from braintree.exceptions.unexpected_error import UnexpectedError
5+
from braintree.util.graphql_client import GraphQLClient
6+
7+
8+
class BankAccountInstantVerificationGateway(object):
9+
def __init__(self, gateway):
10+
self.gateway = gateway
11+
self.config = self.gateway.config
12+
self.graphql_client = self.gateway.graphql_client
13+
14+
CREATE_JWT_MUTATION = """
15+
mutation CreateBankAccountInstantVerificationJwt($input: CreateBankAccountInstantVerificationJwtInput!) {
16+
createBankAccountInstantVerificationJwt(input: $input) {
17+
jwt
18+
}
19+
}
20+
"""
21+
22+
def create_jwt(self, request):
23+
try:
24+
variables = dict({"input": request.to_graphql_variables()})
25+
response = self.graphql_client.query(self.CREATE_JWT_MUTATION, variables)
26+
27+
if "errors" in response:
28+
errors = GraphQLClient.get_validation_errors(response)
29+
return ErrorResult(self.gateway, {"errors": errors, "message": "Validation errors were found"})
30+
31+
data = response.get("data", {})
32+
result = data.get("createBankAccountInstantVerificationJwt", {})
33+
34+
jwt = result.get("jwt")
35+
36+
if jwt is None:
37+
raise UnexpectedError("Couldn't parse response: missing jwt")
38+
39+
jwt_object = BankAccountInstantVerificationJwt(jwt)
40+
return SuccessfulResult({"bank_account_instant_verification_jwt": jwt_object})
41+
42+
except (KeyError, TypeError) as e:
43+
raise UnexpectedError("Couldn't parse response: " + str(e))
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from braintree.attribute_getter import AttributeGetter
2+
3+
class BankAccountInstantVerificationJwt(AttributeGetter):
4+
def __init__(self, jwt):
5+
self.jwt = jwt
6+
7+
@property
8+
def jwt(self):
9+
return self._jwt
10+
11+
@jwt.setter
12+
def jwt(self, value):
13+
self._jwt = value
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
class BankAccountInstantVerificationJwtRequest(object):
2+
def __init__(self):
3+
self._business_name = None
4+
self._return_url = None
5+
self._cancel_url = None
6+
7+
def business_name(self, business_name):
8+
self._business_name = business_name
9+
return self
10+
11+
def return_url(self, return_url):
12+
self._return_url = return_url
13+
return self
14+
15+
def cancel_url(self, cancel_url):
16+
self._cancel_url = cancel_url
17+
return self
18+
19+
20+
def get_business_name(self):
21+
return self._business_name
22+
23+
def get_return_url(self):
24+
return self._return_url
25+
26+
def get_cancel_url(self):
27+
return self._cancel_url
28+
29+
30+
def to_graphql_variables(self):
31+
input_data = {}
32+
33+
if self._business_name is not None:
34+
input_data["businessName"] = self._business_name
35+
if self._return_url is not None:
36+
input_data["returnUrl"] = self._return_url
37+
if self._cancel_url is not None:
38+
input_data["cancelUrl"] = self._cancel_url
39+
40+
return input_data

braintree/braintree_gateway.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from braintree.add_on_gateway import AddOnGateway
22
from braintree.address_gateway import AddressGateway
33
from braintree.apple_pay_gateway import ApplePayGateway
4+
from braintree.bank_account_instant_verification_gateway import BankAccountInstantVerificationGateway
45
from braintree.client_token_gateway import ClientTokenGateway
56
from braintree.configuration import Configuration
67
from braintree.credit_card_gateway import CreditCardGateway
@@ -47,6 +48,7 @@ def __init__(self, config=None, **kwargs):
4748
self.add_on = AddOnGateway(self)
4849
self.address = AddressGateway(self)
4950
self.apple_pay = ApplePayGateway(self)
51+
self.bank_account_instant_verification = BankAccountInstantVerificationGateway(self)
5052
self.client_token = ClientTokenGateway(self)
5153
self.credit_card = CreditCardGateway(self)
5254
self.customer = CustomerGateway(self)

braintree/error_codes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,8 @@ class Transaction(object):
585585
TransactionIsNotEligibleForAdjustment = "915219"
586586
TransactionMustBeInStateAuthorized = "915218"
587587
TransactionSourceIsInvalid = "915133"
588+
TransferTypeIsInvalid = "97501"
589+
TransferDetailsAreRequired = "97510"
588590
TypeIsInvalid = "91523"
589591
TypeIsRequired = "91524"
590592
UnsupportedVoiceAuthorization = "91539"

braintree/payment_method.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ def signature(type):
9191
},
9292
{
9393
"three_d_secure_pass_thru": three_d_secure_pass_thru
94+
},
95+
{
96+
"us_bank_account": [
97+
"ach_mandate_text",
98+
"ach_mandate_accepted_at"
99+
]
94100
}
95101

96102
]

braintree/receiver.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from braintree.attribute_getter import AttributeGetter
2+
3+
class Receiver(AttributeGetter):
4+
def __init__(self, attributes):
5+
AttributeGetter.__init__(self, attributes)

0 commit comments

Comments
 (0)