authorize.netauthorize.net-cim

updateCustomerPaymentProfileRequest documentation error? Can't post updated payment information, E00003


I post JSON to the test API according to this article: https://developer.authorize.net/api/reference/index.html#customer-profiles-update-customer-payment-profile

It clearly states I can include, as received from them, an updated payment element:

paymentProfile  Contains payment information for the customer profile.
Sensitive information that is not being updated can be masked.

This is my entire object:

{
    "updateCustomerPaymentProfileRequest": {
        "merchantAuthentication": {
            "name": "XXXXX",
            "transactionKey": "XXXXX"
        },
        "refId": "XXXXX",
        "customerProfileId": "XXXXX",
        "paymentProfile": {
            "defaultPaymentProfile": true,
            "customerPaymentProfileId": "XXXXX",
            "payment": {
                "creditCard": {
                    "cardNumber": "XXXX1111",
                    "expirationDate": "2023-12"
                }
            },
            "originalNetworkTransId": "XXXXX",
            "originalAuthAmount": 0.0,
            "billTo": {
                "phoneNumber": "XXXXX-XXXXX",
                "firstName": "XXXXX",
                "lastName": "XXXXX",
                "address": "XXXXX XXXXX",
                "city": "XXXXX",
                "state": "XXXXX",
                "zip": "XXXXX-XXXXX",
                "country": "US"
            }
        },
        "validationMode": "testMode"
    }
} 

In return, I get this error:

{
    "messages": {
        "resultCode": "Error",
        "message": [
            {
                "code": "E00003",
                "text":"The element \'paymentProfile\' in namespace \'AnetApi/xml/v1/schema/AnetApiSchema.xsd\' has invalid child element \'payment\' in namespace \'AnetApi/xml/v1/schema/AnetApiSchema.xsd\'."
            }
        ]
    }
}

That makes no sense. It matches the documentation almost exactly. In the error message, they mention the xml schema. When I open it, it shows a different type for the payment profile:

https://api.authorize.net/xml/v1/schema/AnetApiSchema.xsd

shows:

<xs:element name="updateCustomerPaymentProfileRequest">
  <xs:complexType>
    <xs:complexContent>
      <xs:extension base="anet:ANetApiRequest">
        <xs:sequence>
          <xs:element name="customerProfileId" type="anet:numericString"/>
          <xs:element name="paymentProfile" type="anet:customerPaymentProfileExType"/>
          <xs:element name="validationMode" type="anet:validationModeEnum" minOccurs="0"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:element>

where customerPaymentProfileExType is only a customerPaymentProfileId:

<xs:complexType name="customerPaymentProfileExType">
  <xs:complexContent>
    <xs:extension base="anet:customerPaymentProfileType">
      <xs:sequence>
        <xs:element name="customerPaymentProfileId" type="anet:numericString" minOccurs="0"/>
      </xs:sequence>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

If I provide my JSON to match the above specification, I get this error:

{
    "refId": "XXXXX",
    "messages": {
        "resultCode": "Error",
        "message": [
            {
                "code": "E00029",
                "text": "Payment information is required."
            }
        ]
    }
}

Solution

  • Solution: defaultPaymentProfile and customerPaymentProfileId have to be listed AFTER the payment entity inside paymentProfile.

    So do this:

            "paymentProfile": {
                "payment": {
                    "creditCard": {
                        "cardNumber": "XXXX1111",
                        "expirationDate": "2023-12"
                    }
                },
                "defaultPaymentProfile": true,
                "customerPaymentProfileId": "XXXXX"
            },
    

    NOT:

            "paymentProfile": {
                "defaultPaymentProfile": true,
                "customerPaymentProfileId": "XXXXX",
                "payment": {
                    "creditCard": {
                        "cardNumber": "XXXX1111",
                        "expirationDate": "2023-12"
                    }
                },
            },