Skip to content

Commit 210629e

Browse files
braintreepsDavid Johnson
andcommitted
6.29.0
Co-authored-by: David Johnson <djohnson14@paypal.com>
1 parent f8693ee commit 210629e

30 files changed

+1355
-17
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

.github/workflows/security.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Security
2+
3+
permissions:
4+
contents: write # Needed by both CodeQL and dependency review
5+
pull-requests: write # Needed by dependency review
6+
statuses: write # Needed by dependency review (to post checks)
7+
security-events: write # Needed by CodeQL to upload SARIF
8+
packages: read # Needed by CodeQL for private/internal packs
9+
actions: read # Needed by CodeQL to access internal actions
10+
11+
on:
12+
pull_request:
13+
branches: [ master ]
14+
push:
15+
branches: [ master ]
16+
workflow_dispatch:
17+
18+
jobs:
19+
semgrep-php:
20+
uses: PayPal-Braintree/security-workflows/.github/workflows/semgrep-php.yml@main
21+
22+
dependency-review:
23+
uses: PayPal-Braintree/security-workflows/.github/workflows/dependency-review.yml@main

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# Changelog
22

3+
## 6.29.0
4+
5+
* Add Bank Account Instant Verification functionality
6+
* Add `BankAccountInstantVerificationGateway` for creating JWT tokens
7+
* Add `BankAccountInstantVerificationJwt` and `BankAccountInstantVerificationJwtRequest` classes
8+
* Add `bankAccountInstantVerification()` method to main Gateway class
9+
* Add ACH mandate support for US Bank Account transactions
10+
* Add `achMandateText` and `achMandateAcceptedAt` fields to Transaction and PaymentMethod create signatures
11+
* Add `usBankAccount` parameter support for ACH mandate details
12+
* Add `INSTANT_VERIFICATION_ACCOUNT_VALIDATION` as a new US Bank Account verification method
13+
* Add `sender` and `receiver` to `transfer` in `Transaction`
14+
* Add `achRejectReason` field to `Transaction`
15+
* Add `sender` and `receiver` to `transfer` in `Transaction`
16+
* Add `isDeviceToken` and `merchantTokenIdentifier` to `ApplePayCard` and `ApplePayDetails`
17+
* Add `paymentAccountReference` to `ApplePayCardDetails`, `GooglePayCardDetails`, `CreditCardDetails` and `CreditCardVerification`
18+
319
## 6.28.0
420
* Add `upcomingRetryDate` to Transaction
521
* Add `remainingFileEvidenceStorage` to `Dispute`
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace Braintree;
4+
5+
/**
6+
* Provides methods to interact with Bank Account Instant Verification functionality.
7+
*
8+
* This gateway enables merchants to create JWTs for initiating the Open Banking flow
9+
* and retrieve bank account details for display purposes.
10+
*/
11+
class BankAccountInstantVerificationGateway
12+
{
13+
private $_gateway;
14+
private $_http;
15+
private $_config;
16+
private $_graphQLClient;
17+
18+
private static $CREATE_JWT_MUTATION =
19+
'mutation CreateBankAccountInstantVerificationJwt($input: CreateBankAccountInstantVerificationJwtInput!) { ' .
20+
'createBankAccountInstantVerificationJwt(input: $input) {' .
21+
' jwt' .
22+
' }' .
23+
'}';
24+
25+
/**
26+
* BankAccountInstantVerificationGateway constructor.
27+
*
28+
* @param object $gateway The gateway object providing configuration and GraphQL client.
29+
*/
30+
public function __construct($gateway)
31+
{
32+
$this->_gateway = $gateway;
33+
$this->_http = new Http($gateway->config);
34+
$this->_config = $gateway->config;
35+
$this->_graphQLClient = $gateway->graphQLClient;
36+
}
37+
38+
/**
39+
* Creates a Bank Account Instant Verification JWT for initiating the Open Banking flow.
40+
*
41+
* @param BankAccountInstantVerificationJwtRequest $request the JWT creation request containing business name and redirect URLs
42+
*
43+
* @return Result\Successful|Result\Error a Result containing the JWT and client mutation ID
44+
*/
45+
public function createJwt($request)
46+
{
47+
$response = $this->_graphQLClient->query(self::$CREATE_JWT_MUTATION, $request->toGraphQLVariables());
48+
$errors = GraphQLClient::getValidationErrors($response);
49+
50+
if ($errors) {
51+
return new Result\Error(['errors' => $errors]);
52+
}
53+
54+
try {
55+
$data = $response['data'];
56+
$result = $data['createBankAccountInstantVerificationJwt'];
57+
58+
$jwt = $result['jwt'];
59+
60+
$jwtObject = BankAccountInstantVerificationJwt::factory([
61+
'jwt' => $jwt
62+
]);
63+
64+
return new Result\Successful($jwtObject, 'bankAccountInstantVerificationJwt');
65+
} catch (\Exception $e) {
66+
throw new Exception\Unexpected("Couldn't parse response: " . $e->getMessage());
67+
}
68+
}
69+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace Braintree;
4+
5+
/**
6+
* Represents a Bank Account Instant Verification JWT containing a JWT.
7+
*
8+
* @property-read string $jwt
9+
*/
10+
class BankAccountInstantVerificationJwt extends Base
11+
{
12+
protected $_attributes = [
13+
'jwt'
14+
];
15+
16+
/**
17+
* factory method: returns an instance of BankAccountInstantVerificationJwt
18+
* from given attributes
19+
*
20+
* @param array $attributes attributes for the verification JWT
21+
*
22+
* @return BankAccountInstantVerificationJwt
23+
*/
24+
public static function factory($attributes)
25+
{
26+
$instance = new self();
27+
$instance->_initialize($attributes);
28+
29+
return $instance;
30+
}
31+
32+
/**
33+
* Initializes the instance with given attributes
34+
*
35+
* @param array $attributes
36+
*/
37+
protected function _initialize($attributes)
38+
{
39+
$this->_attributes = $attributes;
40+
}
41+
42+
/**
43+
* Returns the JWT for Bank Account Instant Verification.
44+
*
45+
* @return string the JWT
46+
*/
47+
public function getJwt()
48+
{
49+
return $this->jwt;
50+
}
51+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
namespace Braintree;
4+
5+
/**
6+
* Provides a fluent interface to build requests for creating Bank Account Instant Verification JWTs.
7+
*/
8+
class BankAccountInstantVerificationJwtRequest
9+
{
10+
private $_businessName;
11+
private $_returnUrl;
12+
private $_cancelUrl;
13+
14+
/**
15+
* Sets the officially registered business name for the merchant.
16+
*
17+
* @param string $businessName the business name
18+
*
19+
* @return BankAccountInstantVerificationJwtRequest
20+
*/
21+
public function businessName($businessName)
22+
{
23+
$this->_businessName = $businessName;
24+
return $this;
25+
}
26+
27+
/**
28+
* Sets the URL to redirect the consumer after successful account selection.
29+
*
30+
* @param string $returnUrl the return URL
31+
*
32+
* @return BankAccountInstantVerificationJwtRequest
33+
*/
34+
public function returnUrl($returnUrl)
35+
{
36+
$this->_returnUrl = $returnUrl;
37+
return $this;
38+
}
39+
40+
/**
41+
* Sets the URL to redirect the consumer upon cancellation of the Open Banking flow.
42+
*
43+
* @param string $cancelUrl the cancel URL
44+
*
45+
* @return BankAccountInstantVerificationJwtRequest
46+
*/
47+
public function cancelUrl($cancelUrl)
48+
{
49+
$this->_cancelUrl = $cancelUrl;
50+
return $this;
51+
}
52+
53+
54+
/**
55+
* Gets the business name.
56+
*
57+
* @return string
58+
*/
59+
public function getBusinessName()
60+
{
61+
return $this->_businessName;
62+
}
63+
64+
/**
65+
* Gets the return URL.
66+
*
67+
* @return string
68+
*/
69+
public function getReturnUrl()
70+
{
71+
return $this->_returnUrl;
72+
}
73+
74+
/**
75+
* Gets the cancel URL.
76+
*
77+
* @return string
78+
*/
79+
public function getCancelUrl()
80+
{
81+
return $this->_cancelUrl;
82+
}
83+
84+
85+
/**
86+
* Converts the request to GraphQL variables format
87+
*
88+
* @return array
89+
*/
90+
public function toGraphQLVariables()
91+
{
92+
$variables = [];
93+
$input = [];
94+
95+
if ($this->_businessName !== null) {
96+
$input['businessName'] = $this->_businessName;
97+
}
98+
if ($this->_returnUrl !== null) {
99+
$input['returnUrl'] = $this->_returnUrl;
100+
}
101+
if ($this->_cancelUrl !== null) {
102+
$input['cancelUrl'] = $this->_cancelUrl;
103+
}
104+
105+
$variables['input'] = $input;
106+
return $variables;
107+
}
108+
}

lib/Braintree/ClientTokenGateway.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public function generate($params = [])
3939
$params["version"] = ClientToken::DEFAULT_VERSION;
4040
}
4141

42-
Util::verifyKeys(self::generateSignature(), $params);
42+
$this->conditionallyVerifyKeys($params);
4343
$generateParams = ["client_token" => $params];
4444

4545
return $this->_doGenerate('/client_token', $generateParams);

lib/Braintree/Configuration.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,16 @@ public function graphQLBaseUrl()
631631
return sprintf('%s://%s:%d/graphql', $this->protocol(), $this->graphQLServerName(), $this->graphQLPortNumber());
632632
}
633633

634+
/**
635+
* returns the base URL for Braintree's Atmosphere service based on config values
636+
*
637+
* @return string Braintree Atmosphere URL
638+
*/
639+
public function atmosphereBaseUrl()
640+
{
641+
return sprintf('%s://%s:%d', $this->protocol(), $this->atmosphereServerName(), $this->atmospherePortNumber());
642+
}
643+
634644
/**
635645
* sets the merchant path based on merchant ID
636646
*
@@ -687,6 +697,19 @@ public function graphQLPortNumber()
687697
return getenv("GRAPHQL_PORT") ?: 8080;
688698
}
689699

700+
/**
701+
* returns the port number for Atmosphere service depending on environment
702+
*
703+
* @return integer atmosphere portnumber
704+
*/
705+
public function atmospherePortNumber()
706+
{
707+
if ($this->sslOn()) {
708+
return 443;
709+
}
710+
return getenv("ATMOSPHERE_PORT") ?: 8080;
711+
}
712+
690713
/**
691714
* Specifies whether or not a proxy is properly configured
692715
*
@@ -776,6 +799,33 @@ public function graphQLServerName()
776799
return $graphQLServerName;
777800
}
778801

802+
/**
803+
* returns Braintree Atmosphere server name depending on environment
804+
*
805+
* @return string atmosphere domain name
806+
*/
807+
public function atmosphereServerName()
808+
{
809+
switch ($this->_environment) {
810+
case 'production':
811+
$atmosphereServerName = 'payments.braintree-api.com';
812+
break;
813+
case 'qa':
814+
$atmosphereServerName = 'payments-qa.dev.braintree-api.com';
815+
break;
816+
case 'sandbox':
817+
$atmosphereServerName = 'payments.sandbox.braintree-api.com';
818+
break;
819+
case 'development':
820+
case 'integration':
821+
default:
822+
$atmosphereServerName = 'atmosphere.bt.local';
823+
break;
824+
}
825+
826+
return $atmosphereServerName;
827+
}
828+
779829
/**
780830
* returns boolean indicating SSL is on or off for this session,
781831
* depending on environment

lib/Braintree/Error/Codes.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,10 @@ class Codes
639639

640640
const TRANSACTION_TRANSACTION_SOURCE_IS_INVALID = '915133';
641641

642+
643+
const TRANSFER_DETAILS_NOT_APPLICABLE = '97501';
644+
const TRANSFER_DETAILS_NOT_AVAILABLE = '97510';
645+
642646
const US_BANK_ACCOUNT_VERIFICATION_NOT_CONFIRMABLE = '96101';
643647
const US_BANK_ACCOUNT_VERIFICATION_MUST_BE_MICRO_TRANSFERS_VERIFICATION = '96102';
644648
const US_BANK_ACCOUNT_VERIFICATION_AMOUNTS_DO_NOT_MATCH = '96103';

lib/Braintree/Gateway.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,4 +298,15 @@ public function webhookTesting()
298298
{
299299
return new WebhookTestingGateway($this);
300300
}
301+
302+
/**
303+
* Returns a BankAccountInstantVerificationGateway for interacting with
304+
* Bank Account Instant Verification functionality.
305+
*
306+
* @return BankAccountInstantVerificationGateway
307+
*/
308+
public function bankAccountInstantVerification()
309+
{
310+
return new BankAccountInstantVerificationGateway($this);
311+
}
301312
}

0 commit comments

Comments
 (0)