Skip to content

Commit

Permalink
3.18.0
Browse files Browse the repository at this point in the history
Co-authored-by: Sara Vasquez <saravasquez@paypal.com>
Co-authored-by: Debra Do <debdo@paypal.com>
  • Loading branch information
3 people committed Oct 18, 2023
1 parent 8a55da7 commit bdfe808
Show file tree
Hide file tree
Showing 12 changed files with 278 additions and 43 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog

## 3.18.0

- Add `arrivalDate` and `ticketIssuerAddress` to `Transaction.sale` request
- Add `SubscriptionBillingSkipped` to `WebhookNotification.Kind`
- Add `debitNetwork` to `Transaction.sale`
- Add `DebitNetwork` enum to `CreditCard`
- Add `debitNetwork` to search criteria in `Transaction.search`

## 3.17.0

- Add `merchantTokenIdentifier` and `sourceCardLast4` to `ApplePayCard` and `ApplePayDetail`
Expand Down
25 changes: 25 additions & 0 deletions lib/braintree/credit_card.js
Expand Up @@ -51,6 +51,31 @@ class CreditCard extends AttributeSetter {
Unknown: "Unknown",
};

this.DebitNetwork = {
Accel: "ACCEL",
Nyce: "NYCE",
Pulse: "PULSE",
Star: "STAR",
StarAccess: "STAR_ACCESS",
Maestro: "MAESTRO",
All() {
let all = [];

for (let key in this) {
if (!this.hasOwnProperty(key)) {
continue;
}
let value = this[key];

if (key !== "All") {
all.push(value);
}
}

return all;
},
};

this.Prepaid =
this.Commercial =
this.Payroll =
Expand Down
1 change: 1 addition & 0 deletions lib/braintree/test_values/nonces.js
Expand Up @@ -66,6 +66,7 @@ let Nonces = {
TransactableCountryOfIssuanceCAD: "fake-valid-country-of-issuance-cad-nonce",
TransactableIssuingBankNetworkOnly:
"fake-valid-issuing-bank-network-only-nonce",
TransactablePinlessDebitVisa: "fake-pinless-debit-visa-nonce",
ProcessorDeclinedVisa: "fake-processor-declined-visa-nonce",
ProcessorDeclinedMasterCard: "fake-processor-declined-mastercard-nonce",
ProcessorDeclinedAmEx: "fake-processor-declined-amex-nonce",
Expand Down
124 changes: 89 additions & 35 deletions lib/braintree/transaction_gateway.js
Expand Up @@ -240,6 +240,58 @@ class TransactionGateway extends Gateway {
"descriptor[phone]",
"descriptor[url]",
"discountAmount",
"industry",
"industry[data]",
"industry[data][additionalCharges][amount]",
"industry[data][additionalCharges][kind]",
"industry[data][advancedDeposit]",
"industry[data][arrivalDate]",
"industry[data][checkInDate]",
"industry[data][checkOutDate]",
"industry[data][customerCode]",
"industry[data][departureDate]",
"industry[data][fareAmount]",
"industry[data][feeAmount]",
"industry[data][fireSafe]",
"industry[data][folioNumber]",
"industry[data][issuedDate]",
"industry[data][issuingCarrierCode]",
"industry[data][legs][arrivalAirportCode]",
"industry[data][legs][arrivalTime]",
"industry[data][legs][carrierCode]",
"industry[data][legs][conjunctionTicket]",
"industry[data][legs][couponNumber]",
"industry[data][legs][departureAirportCode]",
"industry[data][legs][departureDate]",
"industry[data][legs][departureTime]",
"industry[data][legs][endorsementOrRestrictions]",
"industry[data][legs][exchangeTicket]",
"industry[data][legs][fareAmount]",
"industry[data][legs][fareBasisCode]",
"industry[data][legs][feeAmount]",
"industry[data][legs][flightNumber]",
"industry[data][legs][serviceClass]",
"industry[data][legs][stopoverPermitted]",
"industry[data][legs][taxAmount]",
"industry[data][lodgingCheckInDate]",
"industry[data][lodgingCheckOutDate]",
"industry[data][lodgingName]",
"industry[data][noShow]",
"industry[data][passengerFirstName]",
"industry[data][passengerLastName]",
"industry[data][passengerMiddleInitial]",
"industry[data][passengerTitle]",
"industry[data][propertyPhone]",
"industry[data][restrictedTicket]",
"industry[data][roomRate]",
"industry[data][roomTax]",
"industry[data][taxAmount]",
"industry[data][ticketIssuerAddress]",
"industry[data][ticketNumber]",
"industry[data][travelAgencyName]",
"industry[data][travelAgencyCode]",
"industry[data][travelPackage]",
"industry[industryType]",
"lineItems[commodityCode]",
"lineItems[description]",
"lineItems[discountAmount]",
Expand Down Expand Up @@ -408,55 +460,57 @@ class TransactionGateway extends Gateway {
"paypalAccount[paymentId]",
"productSku",
"industry",
"industry[industryType]",
"industry[data]",
"industry[data][folioNumber]",
"industry[data][additionalCharges][kind]",
"industry[data][additionalCharges][amount]",
"industry[data][advancedDeposit]",
"industry[data][arrivalDate]",
"industry[data][checkInDate]",
"industry[data][checkOutDate]",
"industry[data][travelPackage]",
"industry[data][lodgingCheckInDate]",
"industry[data][lodgingCheckOutDate]",
"industry[data][departureDate]",
"industry[data][lodgingName]",
"industry[data][roomRate]",
"industry[data][roomTax]",
"industry[data][passengerFirstName]",
"industry[data][passengerLastName]",
"industry[data][passengerMiddleInitial]",
"industry[data][passengerTitle]",
"industry[data][issuedDate]",
"industry[data][travelAgencyName]",
"industry[data][travelAgencyCode]",
"industry[data][ticketNumber]",
"industry[data][issuingCarrierCode]",
"industry[data][customerCode]",
"industry[data][departureDate]",
"industry[data][fareAmount]",
"industry[data][feeAmount]",
"industry[data][taxAmount]",
"industry[data][restrictedTicket]",
"industry[data][noShow]",
"industry[data][advancedDeposit]",
"industry[data][fireSafe]",
"industry[data][propertyPhone]",
"industry[data][folioNumber]",
"industry[data][issuedDate]",
"industry[data][issuingCarrierCode]",
"industry[data][legs][arrivalAirportCode]",
"industry[data][legs][arrivalTime]",
"industry[data][legs][carrierCode]",
"industry[data][legs][conjunctionTicket]",
"industry[data][legs][exchangeTicket]",
"industry[data][legs][couponNumber]",
"industry[data][legs][serviceClass]",
"industry[data][legs][carrierCode]",
"industry[data][legs][fareBasisCode]",
"industry[data][legs][flightNumber]",
"industry[data][legs][departureDate]",
"industry[data][legs][departureAirportCode]",
"industry[data][legs][departureDate]",
"industry[data][legs][departureTime]",
"industry[data][legs][arrivalAirportCode]",
"industry[data][legs][arrivalTime]",
"industry[data][legs][stopoverPermitted]",
"industry[data][legs][endorsementOrRestrictions]",
"industry[data][legs][exchangeTicket]",
"industry[data][legs][fareAmount]",
"industry[data][legs][fareBasisCode]",
"industry[data][legs][feeAmount]",
"industry[data][legs][flightNumber]",
"industry[data][legs][serviceClass]",
"industry[data][legs][stopoverPermitted]",
"industry[data][legs][taxAmount]",
"industry[data][legs][endorsementOrRestrictions]",
"industry[data][additionalCharges][kind]",
"industry[data][additionalCharges][amount]",
"industry[data][lodgingCheckInDate]",
"industry[data][lodgingCheckOutDate]",
"industry[data][lodgingName]",
"industry[data][noShow]",
"industry[data][passengerFirstName]",
"industry[data][passengerLastName]",
"industry[data][passengerMiddleInitial]",
"industry[data][passengerTitle]",
"industry[data][propertyPhone]",
"industry[data][restrictedTicket]",
"industry[data][roomRate]",
"industry[data][roomTax]",
"industry[data][taxAmount]",
"industry[data][ticketIssuerAddress]",
"industry[data][ticketNumber]",
"industry[data][travelAgencyCode]",
"industry[data][travelAgencyName]",
"industry[data][travelPackage]",
"industry[industryType]",
"installments[count]",
"discountAmount",
"shippingAmount",
Expand Down
14 changes: 9 additions & 5 deletions lib/braintree/transaction_search.js
Expand Up @@ -66,15 +66,19 @@ class TransactionSearch extends AdvancedSearch {
CreditCard.CustomerLocation.US,
],
});
this.multipleValueField("debitNetwork", {
// eslint-disable-next-line new-cap
allows: CreditCard.DebitNetwork.All(),
});
this.multipleValueField("ids");
this.multipleValueField("user");
this.multipleValueField("paymentInstrumentType");
this.multipleValueField("merchantAccountId");
this.multipleValueField("status", { allows: Transaction.Status.All() }); // eslint-disable-line new-cap
this.multipleValueField("paymentInstrumentType");
this.multipleValueField("reasonCode");
this.multipleValueField("source");
this.multipleValueField("type", { allows: Transaction.Type.All() }); // eslint-disable-line new-cap
this.multipleValueField("status", { allows: Transaction.Status.All() }); // eslint-disable-line new-cap
this.multipleValueField("storeIds");
this.multipleValueField("reasonCode");
this.multipleValueField("type", { allows: Transaction.Type.All() }); // eslint-disable-line new-cap
this.multipleValueField("user");
this.keyValueFields("refund");
this.rangeFields(
"amount",
Expand Down
1 change: 1 addition & 0 deletions lib/braintree/webhook_notification.js
Expand Up @@ -62,6 +62,7 @@ const Kind = {
OAuthAccessRevoked: "oauth_access_revoked",
RecipientUpdatedGrantedPaymentMethod:
"recipient_updated_granted_payment_method",
SubscriptionBillingSkipped: "subscription_billing_skipped",
SubscriptionCanceled: "subscription_canceled",
SubscriptionChargedSuccessfully: "subscription_charged_successfully",
SubscriptionChargedUnsuccessfully: "subscription_charged_unsuccessfully",
Expand Down
11 changes: 11 additions & 0 deletions lib/braintree/webhook_testing_gateway.js
Expand Up @@ -110,6 +110,8 @@ class WebhookTestingGateway extends Gateway {
return this.subjectXmlForSubMerchantAccountApproved(id);
case WebhookNotification.Kind.SubMerchantAccountDeclined:
return this.subjectXmlForSubMerchantAccountDeclined(id);
case WebhookNotification.Kind.SubscriptionBillingSkipped:
return this.subjectXmlForSubscriptionBillingSkipped(id);
case WebhookNotification.Kind.SubscriptionChargedSuccessfully:
return this.subjectXmlForSubscriptionChargedSuccessfully(id);
case WebhookNotification.Kind.SubscriptionChargedUnsuccessfully:
Expand Down Expand Up @@ -444,6 +446,15 @@ class WebhookTestingGateway extends Gateway {
</subscription>`;
}

subjectXmlForSubscriptionBillingSkipped(id) {
return `<subscription>
<id>${id}</id>
<transactions type="array"></transactions>
<add_ons type="array"></add_ons>
<discounts type="array"></discounts>
</subscription>`;
}

subjectXmlForSubscriptionChargedSuccessfully(id) {
return `<subscription>
<id>${id}</id>
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "braintree",
"version": "3.17.0",
"version": "3.18.0",
"description": "A library for server-side integrating with Braintree.",
"keywords": [
"braintree",
Expand Down
66 changes: 65 additions & 1 deletion test/integration/braintree/transaction_gateway_spec.js
Expand Up @@ -5047,6 +5047,8 @@ describe("TransactionGateway", function () {
feeAmount: "10.00",
taxAmount: "20.00",
restrictedTicket: false,
arrivalDate: "2023-01-01",
ticketIssuerAddress: "ti-address",
legs: [
{
conjunctionTicket: "CJ0001",
Expand Down Expand Up @@ -5101,6 +5103,68 @@ describe("TransactionGateway", function () {
);
});

it("allows submitting a transaction with travel flight industry data", function (done) {
let transactionParams = {
amount: "5.00",
merchantAccountId: specHelper.fakeFirstDataMerchantAccountId,
creditCard: {
number: "5105105105105100",
expirationDate: "05/12",
},
};

specHelper.defaultGateway.transaction.sale(
transactionParams,
(err, response) => {
let submitForSettlementParams = {
industry: {
industryType: Transaction.IndustryData.TravelAndFlight,
data: {
passengerFirstName: "John",
issuedDate: "2018-01-01",
ticketNumber: "ticket-number",
issuingCarrierCode: "AA",
restrictedTicket: false,
arrivalDate: "2023-01-01",
ticketIssuerAddress: "ti-address",
legs: [
{
serviceClass: "Y",
carrierCode: "AA",
fareBasisCode: "W",
flightNumber: "AA100",
departureDate: "2018-01-02",
departureAirportCode: "MDW",
departureTime: "08:00",
arrivalAirportCode: "ATX",
arrivalTime: "10:00",
stopoverPermitted: false,
fareAmount: "35.00",
},
],
},
},
};

specHelper.defaultGateway.transaction.submitForSettlement(
response.transaction.id,
null,
submitForSettlementParams,
function (err, response) {
assert.isNull(err);
assert.isTrue(response.success);
assert.equal(
response.transaction.status,
"submitted_for_settlement"
);

done();
}
);
}
);
});

it("fails with a validation error when travel flight industry data is invalid", function (done) {
let transactionParams = {
amount: "10.0",
Expand Down Expand Up @@ -8275,7 +8339,7 @@ describe("TransactionGateway", function () {
assert.isTrue(response.success);
assert.equal(response.transaction.type, "sale");
assert.equal(response.transaction.amount, "5.00");
assert.isUndefined(response.transaction.retried);
assert.isFalse(response.transaction.retried);
assert.isEmpty(response.transaction.retryIds);
assert.isNull(response.transaction.retriedTransactionId);
assert.equal(response.transaction.processorResponseCode, "1000");
Expand Down

0 comments on commit bdfe808

Please sign in to comment.