Validation errors will be returned on error result objects when we can't process the API call because parameters are invalid. Validation errors contain the following:

  • code - for programmatic consumption
  • message - for human consumption
  • attribute - the parameter that caused an error

Hierarchy

Errors are returned in a hierarchy that matches the parameter hierarchy. For example, when creating a customer with a credit card and billing address, the credit card is nested under customer, and the billing address under credit card.

Node.js
gateway.customer.create({
  email: "invalidEmail",
  creditCard: {
    number: "notNumeric",
    billingAddress: {
      countryName: "notAValidCountry"
    }
  }
}, function (err, result) {
});

You can get errors at all levels, errors at a specific level, or errors at a specific level on a specific attribute.

All errors on all levels

To get the errors on all levels, you can iterate over result.errors.deepErrors(). deepErrors() returns an array of hashes representing the errors.

Node.js
gateway.customer.create({
 // ...
}, function (err, result) {
  var deepErrors = result.errors.deepErrors();

  for (var i in deepErrors) {
    if (deepErrors.hasOwnProperty(i)) {
      console.log(deepErrors[i].code);
      console.log(deepErrors[i].message);
      console.log(deepErrors[i].attribute);
    }
  }
});

Errors at specific levels

To get errors at a specific level, use the for method. The attribute will indicate which attribute is invalid.

Node.js
gateway.customer.create({
  // ...
}, function (err, result) {
  var errors = result.errors;

  var customerErrors = errors.for("customer").deepErrors();
  for (var i in customerErrors) {
    if (customerErrors.hasOwnProperty(i)) {
      console.log(customerErrors[i].code);
      console.log(customerErrors[i].message);
      console.log(customerErrors[i].attribute);
    }
  }

  var creditCardErrors = errors.for("customer").for("creditCard").deepErrors();
  for (var i in creditCardErrors) {
    if (creditCardErrors.hasOwnProperty(i)) {
      console.log(creditCardErrors[i].code);
      console.log(creditCardErrors[i].message);
      console.log(creditCardErrors[i].attribute);
    }
  }

  var billingAddressErrors = errors.for("customer").for("creditCard").for("billingAddress").deepErrors();
  for (var i in billingAddressErrors) {
    if (billingAddressErrors.hasOwnProperty(i)) {
      console.log(billingAddressErrors[i].code);
      console.log(billingAddressErrors[i].message);
      console.log(billingAddressErrors[i].attribute);
    }
  }
});

From a specific level, you can get the number of errors at that level using length.

Node.js
result.errors.for("customer").length;
// number of errors only on customer

result.errors.for("customer").for("creditCard").length;
// number of errors only on credit card

Errors on specific attribute

You can also get errors at a specific level on a specific attribute. This is useful if you want to display error messages inline in your forms.

Node.js
result.errors.for("customer").on("email");
result.errors.for("customer").for("creditCard").on("number");
result.errors.for("customer").for("creditCard").for("billingAddress").on("countryName");

Base errors

Sometimes validation errors aren't caused by a specific input parameter. For example, canceled subscriptions can't be updated. For these validation errors, we use an attribute named "base" for the validation error.

Node.js
gateway.subscription.update("theSubscriptionId", {
  price: "10.00"
}, function (err, result) {
  var baseErrors = result.errors.for("subscription").on("base");
});

Errors on add-ons/discounts

It is possible to add, update and remove many add-ons and discounts at once. If any of the add-ons or discounts contain errors, these errors will be indexed based on the order of the add-on or discount in the request (beginning at 0).

Node.js
gateway.subscription.create({
  paymentMethodToken: "thePaymentMethodToken",
  planId: "thePlanId",
  addOns: {
    update: [
      { existingId: "increase_10", amount: "invalid" },
      { existingId: "increase_20", quantity: -2 }
    ]
  }
}, function (err, result) {
  var error1 = result.errors.for("subscription").for("addOns").for("update").forIndex(0).on("amount");
  var error2 = result.errors.for("subscription").for("addOns").for("update").forIndex(1).on("quantity");
});

See also