Reputation: 11568
I am using the updateCustomerPaymentProfile
endpoint to try to update a payment profile. This works well, except for the presence of one field: defaultPaymentProfile
.
There are two different issues.
The docs say defaultPaymentProfile
is an expected field, but the type does not allow it in ruby SDK, see in the official source code:
I opened a Github issue about this.
I then monkey patched the type as following:
module AuthorizeNet::API
class CustomerPaymentProfileExType
xml_accessor :defaultPaymentProfile
end
end
After that, it accepts to send the request but I receive an error response as following:
AuthorizeNetException: E00003: The element 'paymentProfile' in namespace
'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has invalid child element
'defaultPaymentProfile' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd
Which is the second issue...
defaultPaymentProfile
when updating a payment profileFor the record, I dumped the raw XML that is sent to the API once I patched the SDK to be able to actually reach the API:
<updateCustomerPaymentProfileRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
<merchantAuthentication>
<name>REDACTED</name>
<transactionKey>REDACTED</transactionKey>
</merchantAuthentication>
<customerProfileId>REDACTED</customerProfileId>
<paymentProfile>
<customerType>individual</customerType>
<billTo>
<firstName>REDACTED</firstName>
<lastName>REDACTED</lastName>
<address>REDACTED</address>
<city>REDACTED</city>
<state>REDACTED</state>
<zip>REDACTED</zip>
<country>REDACTED</country>
<phoneNumber>REDACTED</phoneNumber>
</billTo>
<payment>
<creditCard>
<cardNumber>XXXX4242</cardNumber>
<expirationDate>2022-03</expirationDate>
</creditCard>
</payment>
<customerPaymentProfileId>REDACTED</customerPaymentProfileId>
<!-- This XML passes fine without the line below -->
<defaultPaymentProfile>true</defaultPaymentProfile>
</paymentProfile>
<validationMode>liveMode</validationMode>
</updateCustomerPaymentProfileRequest>
This looks exactly the same as the request suggested by the official API docs, yet, the server respond with a E00003
error that I already shared above.
As a reference, the block of ruby code that I am using:
profile = AuthorizeNet::API::CustomerPaymentProfileExType.new
profile.customerPaymentProfileId = current_profile.customerPaymentProfileId
profile.billTo = billTo
profile.payment = AuthorizeNet::API::PaymentType.new(
AuthorizeNet::API::CreditCardType.new(
cc_data.cardNumber, cc_data.expirationDate
)
)
profile.taxId = user.tax_id if user.tax_id
profile.defaultPaymentProfile = true
profile.customerType = 'individual'
request = AuthorizeNet::API::UpdateCustomerPaymentProfileRequest.new
request.paymentProfile = profile
request.customerProfileId = customer_profile_id
request.validationMode = AuthorizeNet::API::ValidationModeEnum::LiveMode
response = transaction.update_customer_payment_profile(request)
What am I doing wrong?
Upvotes: 0
Views: 271
Reputation: 11568
Thanks to @John Conde, I could fix the issue. The request payload is refused because the properties are not in the right order. 🤷
If you want to set an existing payment profile as the default one using the ruby SDK, you can do so by defining yourself the correct type, as following:
module AuthorizeNet::API
class CustomerPaymentProfileExTypePatched
include ROXML
xml_accessor :customerType
xml_accessor :billTo, as: AuthorizeNet::API::CustomerAddressType
xml_accessor :payment, as: AuthorizeNet::API::PaymentType
xml_accessor :driversLicense, as: AuthorizeNet::API::DriversLicenseType
xml_accessor :taxId
xml_accessor :defaultPaymentProfile
xml_accessor :subsequentAuthInformation
xml_accessor :customerPaymentProfileId
def initialize(customerType = nil, billTo = nil, payment = nil, driversLicense = nil, taxId = nil, defaultPaymentProfile = nil, subsequentAuthInformation = nil, customerPaymentProfileId = nil)
@customerType = customerType
@billTo = billTo
@payment = payment
@driversLicense = driversLicense
@taxId = taxId
@defaultPaymentProfile = defaultPaymentProfile
@subsequentAuthInformation = subsequentAuthInformation
@customerPaymentProfileId = customerPaymentProfileId
end
end
end
Then you can just use this type in your code:
profile = AuthorizeNet::API::CustomerPaymentProfileExTypePatched.new
Upvotes: 0
Reputation: 219794
The order of the elements matter. Move
<defaultPaymentProfile>true</defaultPaymentProfile>`
above
<customerPaymentProfileId>REDACTED</customerPaymentProfileId>`
<updateCustomerPaymentProfileRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
<merchantAuthentication>
<name>REDACTED</name>
<transactionKey>REDACTED</transactionKey>
</merchantAuthentication>
<customerProfileId>REDACTED</customerProfileId>
<paymentProfile>
<customerType>individual</customerType>
<billTo>
<firstName>REDACTED</firstName>
<lastName>REDACTED</lastName>
<address>REDACTED</address>
<city>REDACTED</city>
<state>REDACTED</state>
<zip>REDACTED</zip>
<country>REDACTED</country>
<phoneNumber>REDACTED</phoneNumber>
</billTo>
<payment>
<creditCard>
<cardNumber>XXXX4242</cardNumber>
<expirationDate>2022-03</expirationDate>
</creditCard>
</payment>
<defaultPaymentProfile>true</defaultPaymentProfile>
<customerPaymentProfileId>REDACTED</customerPaymentProfileId>
</paymentProfile>
<validationMode>liveMode</validationMode>
</updateCustomerPaymentProfileRequest>
Upvotes: 1