【问题标题】:Authorize.net shows E00040 when Creating Subscription from Customer ProfileAuthorize.net 从客户资料创建订阅时显示 E00040
【发布时间】:2021-08-02 23:12:01
【问题描述】:

我正在使用客户资料在 Authorize.net 中创建 ARB 订阅。这是我的流程:

  1. 创建客户和付款资料。
  2. 通过身份验证捕获创建第一个月的付款。
  3. 使用此客户资料创建 ARB 订阅。

此处 1 & 2 成功完成,但第三步显示错误:E00040,找不到记录。 仅当我在创建新配置文件后创建订阅时才会出现此错误。如果我在一段时间后使用相同的客户资料创建 ARB 订阅,它工作正常。 如果有人可以在这种情况下帮助我,那将非常有用。提前致谢。

 const profile = await subscriptionHelper.createPaymentProfile(userData, body.CreditCardPayment, body.shippingAddress)

  if (profile.error) {
    const error = helper.createErrorResponse({
      status: 403,
      error: 'Supplier Authorize profile error',
      message: profile.error,
    });
    return res.send(error)
  }

  //charging the current customer profile

  subscriptionHelper.chargePaymentProfile(
    planDetail.amount,
    profile.authorizenet_profileId,
    profile.authorizenet_paymentProfileId,
    async (err, paymentDetails) => {
      console.log("error==>", err);
      if (err) {
        const error = helper.createErrorResponse({
          status: 403,
          error: 'Transaction Failed',
          message: err,
        });
        return res.send(error)
      }

      //creating subscription
      const subscription_details = {
        interval_length: planDetail.PlanType.dataValues.length,
        interval_unit: planDetail.PlanType.dataValues.name,
        name: planDetail.PlanType.dataValues.detail
      }
      const startDate = moment().add(subscription_details.interval_length, subscription_details.interval_unit).format("YYYY-MM-DD")

      subscription_details.start_date = startDate

      subscriptionHelper.createSubscription(
        profile.authorizenet_profileId,
        profile.authorizenet_paymentProfileId,
        planDetail.amount,
        subscription_details,
        async (err, subscriptionId) => {
          console.log("err===>", err);
          console.log("subscriptionId", subscriptionId);
          if (err) {
            const error =  helper.createErrorResponse({
              status: 403,
              error: 'Subscription Failed',
              message: err,
            });
            return res.send(error)
          }
         
          return res.send(helper.createSuccessResponse({subscriptionId}, {
            message: 'subscription created succesfully',
          })) ;
        }
      )
    }
  )
exports.createPaymentProfile = async (user, CreditCardPayment, address) => {
    try {
        const checkProfile = await subscriptionRepo.getAuthorizeProfile({ supplier_id: user.id })
        console.log("checkProfile==>",checkProfile);
        if (!checkProfile) {
            return await authorize.createCustomerProfile(user, CreditCardPayment, address).then(async res => {
                try {
                    let paymentProfileId = JSON.parse(res.authorizeCustomerPaymentProfileIdList.numericString[0])

                    let newProfile = await subscriptionRepo.createAuthorizenetProfile({
                        supplier_id: user.id,
                        authorizenet_profileId: res.authorizeCustomerProfileID,
                        authorizenet_paymentProfileId: paymentProfileId,
                        name_on_card: CreditCardPayment.NameOnCard,
                        last4: CreditCardPayment.CardNumber.substr(CreditCardPayment.CardNumber.length - 4),
                        expiry: `${CreditCardPayment.ExpiryMonth}${CreditCardPayment.ExpiryYear}`
                    })
                    return newProfile
                } catch (e) {
                    console.log("error==>", e.message)
                    return { error: e.message }
                }
            }).catch(err => {
                console.log("error==>", err.message)
                return { error: err.message }
            })
        } else {
            const AuthorizenetProfileData = await subscriptionRepo.getAuthorizeProfile({
                supplier_id: user.id,
                last4: CreditCardPayment.CardNumber.substr(CreditCardPayment.CardNumber.length - 4),
                expiry: `${CreditCardPayment.ExpiryMonth}${CreditCardPayment.ExpiryYear}`
            });

            if (!AuthorizenetProfileData) {
                return await authorize.createCustomerPaymentProfile(
                    checkProfile.authorizenet_profileId,
                    user,
                    CreditCardPayment,
                    address
                ).then(async res => {
                    try {
                        if (res.code == "I00001") {//success code
                            let newProfile = await subscriptionRepo.createAuthorizenetProfile({
                                supplier_id: user.id,
                                authorizenet_profileId: res.customerProfileID,
                                authorizenet_paymentProfileId: res.customerPaymentProfileID,
                                name_on_card: CreditCardPayment.NameOnCard,
                                last4: CreditCardPayment.CardNumber.substr(CreditCardPayment.CardNumber.length - 4),
                                expiry: `${CreditCardPayment.ExpiryMonth}${CreditCardPayment.ExpiryYear}`
                            })

                            return newProfile
                        } else if (res.code == "E00039") {
                            console.log("Card already exists for this profile")
                            return { error: res.error }
                        } else {
                            console.log("invalid card", res.error)
                            return { error: res.error }
                        }

                    } catch (e) {
                        console.log("error==>", e.message)
                        return { error: e.message }
                    }
                }).catch(err => {
                    console.log("error==>", err.message)
                    return { error: err.message }
                })
            } else {
                return AuthorizenetProfileData
            }
        }

    } catch (e) {
        console.log(e);
        return { error: e }
    }
}

exports.chargePaymentProfile = (amount, customerProfileId, customerPaymentProfileId, cb) => {
    authorize.chargeCustomerProfile(
        customerProfileId,
        customerPaymentProfileId,
        amount,
        (error, code, transactionData) =>{
            try{
                if (code == "I00001") { //success code
                    return cb(null,transactionData)

                } else {
                    return cb(error,null)
                }
            }catch(e){
                console.log("err==>",e);
                return callback(e,null)
            }
        }
    )
}
const createCustomerProfile = (user, CreditCardPayment, address) => {
  return new Promise((resolve, reject) => {
    const merchantAuthenticationType = new ApiContracts.MerchantAuthenticationType();
    merchantAuthenticationType.setName(settings.authorizenet.apiLoginId);
    merchantAuthenticationType.setTransactionKey(settings.authorizenet.transactionKey);

    const isCardValid = helper.validateCard(CreditCardPayment.CardNumber, CreditCardPayment.ExpiryMonth, CreditCardPayment.ExpiryYear)
    if (!isCardValid) {
      reject({ message: 'Invalid Card' })
    }
    const creditCard = new ApiContracts.CreditCardType();
    creditCard.setCardNumber(CreditCardPayment.CardNumber);
    creditCard.setExpirationDate(`${CreditCardPayment.ExpiryMonth}${CreditCardPayment.ExpiryYear.substring(2)}`);

    const paymentType = new ApiContracts.PaymentType();
    paymentType.setCreditCard(creditCard);

    const customerAddress = new ApiContracts.CustomerAddressType();
    customerAddress.setFirstName(address.firstname);
    customerAddress.setLastName(address.lastname);
    customerAddress.setAddress(address.line1);
    customerAddress.setCity(address.city);
    customerAddress.setState(address.state);
    customerAddress.setZip(address.pincode);
    customerAddress.setCountry(address.country);
    customerAddress.setPhoneNumber(address.phone);

    const customerPaymentProfileType = new ApiContracts.CustomerPaymentProfileType();
    customerPaymentProfileType.setCustomerType(
      ApiContracts.CustomerTypeEnum.INDIVIDUAL,
    );
    customerPaymentProfileType.setPayment(paymentType);
    customerPaymentProfileType.setBillTo(customerAddress);

    const paymentProfilesList = [];
    paymentProfilesList.push(customerPaymentProfileType);

    const customerProfileType = new ApiContracts.CustomerProfileType();
    customerProfileType.setDescription('Profile description here');
    customerProfileType.setEmail(user.email);
    customerProfileType.setPaymentProfiles(paymentProfilesList);

    const createRequest = new ApiContracts.CreateCustomerProfileRequest();
    createRequest.setProfile(customerProfileType);
    createRequest.setValidationMode(ApiContracts.ValidationModeEnum.TESTMODE);
    createRequest.setMerchantAuthentication(merchantAuthenticationType);

    const ctrl = new ApiControllers.CreateCustomerProfileController(
      createRequest.getJSON(),
    );

    ctrl.execute(function () {
      const apiResponse = ctrl.getResponse();

      const response = new ApiContracts.CreateCustomerProfileResponse(
        apiResponse,
      );

      if (response != null) {
        if (response.getMessages().getResultCode() === ApiContracts.MessageTypeEnum.OK) {
          resolve({
            authorizeCustomerProfileID: response.getCustomerProfileId(),
            authorizeCustomerPaymentProfileIdList: response.getCustomerPaymentProfileIdList()
          });
        } else {
          reject({
            message: `${response
              .getMessages()
              .getMessage()[0]
              .getText()}`
          })
        }
      } else {
        reject({ message: 'Null response received' })
      }
    })

  })
}

const createCustomerPaymentProfile = (authorizeCustomerProfileID, user, creditCardDetails, address) => {
  return new Promise((resolve, reject) => {
    const merchantAuthenticationType = new ApiContracts.MerchantAuthenticationType();
    merchantAuthenticationType.setName(settings.authorizenet.apiLoginId);
    merchantAuthenticationType.setTransactionKey(settings.authorizenet.transactionKey);

    const isCardValid = helper.validateCard(creditCardDetails.CardNumber, creditCardDetails.ExpiryMonth, creditCardDetails.ExpiryYear)
    if (!isCardValid) {
      reject({ message: 'Invalid Card' })
    }
    const creditCard = new ApiContracts.CreditCardType();
    creditCard.setCardNumber(creditCardDetails.CardNumber);
    creditCard.setExpirationDate(`${creditCardDetails.ExpiryMonth}${creditCardDetails.ExpiryYear.substring(2)}`);

    const paymentType = new ApiContracts.PaymentType();
    paymentType.setCreditCard(creditCard);

    const customerAddress = new ApiContracts.CustomerAddressType();
    customerAddress.setFirstName(address.firstname);
    customerAddress.setLastName(address.lastname);
    customerAddress.setAddress(address.line1);
    customerAddress.setCity(address.city);
    customerAddress.setState(address.state);
    customerAddress.setZip(address.pincode);
    customerAddress.setCountry(address.country);
    customerAddress.setPhoneNumber(address.phone);

    const profile = new ApiContracts.CustomerPaymentProfileType();
    profile.setBillTo(customerAddress);
    profile.setPayment(paymentType);

    const createRequest = new ApiContracts.CreateCustomerPaymentProfileRequest();

    createRequest.setMerchantAuthentication(merchantAuthenticationType);
    createRequest.setCustomerProfileId(authorizeCustomerProfileID);
    createRequest.setPaymentProfile(profile);
    const ctrl = new ApiControllers.CreateCustomerPaymentProfileController(
      createRequest.getJSON(),
    );

    ctrl.execute(function () {

      const apiResponse = ctrl.getResponse();

      const response = new ApiContracts.CreateCustomerPaymentProfileResponse(
        apiResponse,
      );

      if (response != null) {
        if (response.getMessages().getResultCode() === ApiContracts.MessageTypeEnum.OK) {
          resolve({
            code: response
              .getMessages()
              .getMessage()[0]
              .getCode(),
            customerPaymentProfileID: response.getCustomerPaymentProfileId(),
            customerProfileID: response.getCustomerProfileId(),
          });
        } else {
          reject({
            message: `${response
              .getMessages()
              .getMessage()[0]
              .getText()}`,
            code: response
              .getMessages()
              .getMessage()[0]
              .getCode(),
          })
        }
      } else {
        reject({ message: 'Null response received' })
      }
    })
  })
}

const chargeCustomerProfile = (
  customerProfileId,
  customerPaymentProfileId,
  amount,
  cb
) => {
  const merchantAuthenticationType = new ApiContracts.MerchantAuthenticationType();
  merchantAuthenticationType.setName(settings.authorizenet.apiLoginId);
  merchantAuthenticationType.setTransactionKey(settings.authorizenet.transactionKey);

  const profileToCharge = new ApiContracts.CustomerProfilePaymentType();
  profileToCharge.setCustomerProfileId(customerProfileId);

  const paymentProfile = new ApiContracts.PaymentProfile();
  paymentProfile.setPaymentProfileId(customerPaymentProfileId);
  profileToCharge.setPaymentProfile(paymentProfile);
  const transactionRequestType = new ApiContracts.TransactionRequestType();
  transactionRequestType.setTransactionType(
    ApiContracts.TransactionTypeEnum.AUTHCAPTURETRANSACTION,
  );
  transactionRequestType.setProfile(profileToCharge);
  transactionRequestType.setAmount(amount);

  const createRequest = new ApiContracts.CreateTransactionRequest();
  createRequest.setMerchantAuthentication(merchantAuthenticationType);
  createRequest.setTransactionRequest(transactionRequestType);

  const ctrl = new ApiControllers.CreateTransactionController(
    createRequest.getJSON(),
  );

  ctrl.execute(function () {
    const apiResponse = ctrl.getResponse();
    const response = new ApiContracts.CreateTransactionResponse(apiResponse);

    if (response != null) {
      if (response.getMessages().getResultCode() == ApiContracts.MessageTypeEnum.OK) {
        if (response.getTransactionResponse().getMessages() != null) {
          return cb(
            undefined,
            response.getMessages().getMessage()[0].getCode(),
            {
              transactionResp: response.getTransactionResponse(),
              customerProfileId: response.getTransactionResponse().getProfile()
                .customerProfileId,
              customerPaymentProfileId: response
                .getTransactionResponse()
                .getProfile().customerPaymentProfileId,
              transactionID: response.getTransactionResponse().getTransId(),
              Response_Code: response.getTransactionResponse().getResponseCode(),
              Message_Code: response
                .getTransactionResponse()
                .getMessages()
                .getMessage()[0]
                .getCode(),
              Description: response
                .getTransactionResponse()
                .getMessages()
                .getMessage()[0]
                .getDescription(),
            }
          );
        }
        let error = 'Failed Transaction';

        if (response.getTransactionResponse().getErrors() != null) {
          error = `${response
            .getTransactionResponse()
            .getErrors()
            .getError()[0]
            .getErrorText()}`;
        }
        return cb(error, undefined, undefined);
      }
      let error = 'Failed Transaction';
      if (
        response.getTransactionResponse() != null &&
        response.getTransactionResponse().getErrors() != null
      ) {
        error = ` ${response
          .getTransactionResponse()
          .getErrors()
          .getError()[0]
          .getErrorText()}`;
        return cb(error, undefined, undefined);
      } else {
        return cb(
          ` ${response
            .getMessages()
            .getMessage()[0]
            .getText()}`,
          response.getMessages().getMessage()[0].getCode(),
          undefined,
        );
      }

    } else {
      return cb('Null Response.', undefined, undefined);
    }
  })

}

const createSubscriptionFromCustomerProfile = (
  customerProfileId,
  customerPaymentProfileId,
  amount,
  subscription_details,
  cb
) => {
  const date = new Date()
  const merchantAuthenticationType = new ApiContracts.MerchantAuthenticationType();
  merchantAuthenticationType.setName(settings.authorizenet.apiLoginId);
  merchantAuthenticationType.setTransactionKey(settings.authorizenet.transactionKey);
  const interval = new ApiContracts.PaymentScheduleType.Interval();
  interval.setLength(subscription_details.interval_length);

  if(subscription_details.interval_unit == "months"){
        interval.setUnit(ApiContracts.ARBSubscriptionUnitEnum.MONTHS);
    }
    if(subscription_details.interval_unit == "days"){
        interval.setUnit(ApiContracts.ARBSubscriptionUnitEnum.DAYS);
    }
  const paymentScheduleType = new ApiContracts.PaymentScheduleType();
    paymentScheduleType.setInterval(interval);
    paymentScheduleType.setStartDate(subscription_details.start_date);
    paymentScheduleType.setTotalOccurrences(9999);

  const customerProfileIdType = new ApiContracts.CustomerProfileIdType();
    customerProfileIdType.setCustomerProfileId(customerProfileId);
    customerProfileIdType.setCustomerPaymentProfileId(customerPaymentProfileId);

  var orderType = new ApiContracts.OrderType();
  orderType.setInvoiceNumber(`${date.getFullYear()}${date.getMonth()+1}${date.getDate()}${date.getHours()}${date.getMinutes()}${date.getSeconds()}${date.getMilliseconds()}`);

  const arbSubscription = new ApiContracts.ARBSubscriptionType();
    arbSubscription.setName(subscription_details.name);
    arbSubscription.setPaymentSchedule(paymentScheduleType);
    arbSubscription.setAmount(amount);
    arbSubscription.setOrder(orderType) // for remove duplication
    arbSubscription.setProfile(customerProfileIdType);

  const createRequest = new ApiContracts.ARBCreateSubscriptionRequest();
    createRequest.setMerchantAuthentication(merchantAuthenticationType);
  createRequest.setSubscription(arbSubscription);
  createRequest.setRefId(`${date.getFullYear()}${date.getMonth()+1}${date.getDate()}${date.getHours()}${date.getMinutes()}${date.getSeconds()}${date.getMilliseconds()}`)

  const ctrl = new ApiControllers.ARBCreateSubscriptionController(
        createRequest.getJSON(),
    );

  ctrl.execute(function() {
    const apiResponse = ctrl.getResponse();

        const response = new ApiContracts.ARBCreateSubscriptionResponse(
            apiResponse,
        );

    if (response != null) {
            if (response.getMessages().getResultCode() == ApiContracts.MessageTypeEnum.OK) {
                console.log(`Subscription Id : ${response.getSubscriptionId()}`);
                return cb(
                    response.getMessages().getMessage()[0].getText(), 
                    response.getMessages().getMessage()[0].getCode(),
                    response.getSubscriptionId()
                );
            }
            return cb(
                response.getMessages().getMessage()[0].getText(),
                response.getMessages().getMessage()[0].getCode(),
                undefined
            );
        }
    return cb('Null Response', undefined, undefined);
  })
}

【问题讨论】:

  • 至少显示第 3 步的代码
  • 我已经添加了代码。

标签: payment-gateway subscription authorize.net


【解决方案1】:

这似乎是一个复制问题,如果请求#1 和请求#3 在完全同步之前命中两个不同的数据中心,则可能会发生这种情况。跨所有数据中心。

可能的解决方案是 (1) 每当发生 E00040 错误时实施重试机制,或 (2) 在两个请求之间添加一个短暂的延迟。

如果您能够重新考虑您的集成流程,会有更好的解决方案。 ARB 与 CIM 可互操作,这意味着每当您创建 ARB 订阅时,系统都会检查是否没有相关的 CIM 配置文件,将创建一个,因此,从技术上讲,如果您的要求允许,您可以从流程中消除 request#1。

【讨论】:

  • 感谢您的回复。我已经安排了一个节点 cron,它将再次重试失败的订阅。步骤#1 仅适用于新用户,因为我正在检查他们是否有使用 Authorize 的客户资料。
猜你喜欢
  • 2018-02-21
  • 2016-01-05
  • 1970-01-01
  • 1970-01-01
  • 2018-02-08
  • 2020-06-03
  • 2012-11-13
  • 1970-01-01
  • 2020-01-11
相关资源
最近更新 更多