I spent a while looking for documentation for sending a tokenized payment authorization request to the CyberSource payments REST API. The documentation shows all possible request bindings, but I was unable to format a sandbox request which would allow me to authorize a card using the payment token rather than the card number. No matter what I would do, I got this result:
"errorInformation" : { "reason" : "INVALID_ACCOUNT", "message" : "Decline - Invalid account number" },
Note that generating a payment profile seems to work fine. I understand that there is a team specifically for handling CyberSource related questions, so I called them, but I was told that the API is in beta, some of the documentation might be missing, and that they were unable to help me. However, it sounded like it should be possible to get the request to succeed, just that there isn't complete documentation for doing so. They also mentioned a "subscriptionID" binding, but I don't see this anywhere in the documentation.
Given that the CyberSource help line wasn't able to answer my question and there is no documentation for this specific case, I understand that I may not get an answer here, but just in case, does anyone happen to know how to authorize a card this way? Again, I want to send an authorize request to the API I linked without using the card number, so the example code which uses the card number won't work for my use case.
Edit: Looking at my request bindings, paymentInformation > customer > customerId seems like it could be the "invalid account number" the response is referring to. However, I don't see any other binding in the request or response for tokenizing the card that would represent this account number, so it seems like I should just be using the payment profile ID or subscription ID.
Hello @rbrandenburg,
I am working on your inquiry, I will get back to you soon.
Thanks,
Vaibhav
Hi @rbrandenburg,
Please make sure you pass the token that you generated through Secure Acceptance Flexible Token API to process payment API, under payment information object like paymentInformation -> customer -> customerID.
Let us know if you have any questions.
Thank you,
Vaibhav
Thanks for the response, but I am still seeing this in the response when I try to authorize using the updated request:
"errorInformation" : { "reason" : "INVALID_ACCOUNT", "message" : "Decline - Invalid account number" },
This is using a new token for a new card. To be clear, the value I should be using is "token" from the "tokenize card" response, correct? Also, is it possible the problem is that I'm hitting the v1 endpoint for tokenizing and the v2 endpoint for authorizing the payment? I tried changing the tokenization request endpoint to v2, but it couldn't find it.
Hello,
Have you passed the token that you generated through Secure Acceptance Flexible Token API to process payment API, under payment information object like paymentInformation -> customer -> customerID.
Also, please send us the following to debug futher.
Thank you,
Vaibhav
Yes, I pass in the token via the customer ID field when sending the request. To answer your questions:
RequestBody: { "clientReferenceInformation" : { "code" : "6280401" }, "processingInformation" : { "capture" : "false", "authorizationOptions" : { "authType" : "STANDARDCAPTURE", "authIndicator" : "0", "ignoreAvsResult" : "false" } }, "orderInformation" : { "billTo" : { [address information] }, "shipTo" : {[address information]},
"amountDetails" : { "totalAmount" : "9.99", "currency" : "USD" } },
"paymentInformation" : { "tokenizedCard" :
{ "expirationYear" : "2022", "number" : "5366041269806291704107", "securityCode" : "000", "expirationMonth" : "01", "type" : "001", "transactionType" : "1" },
"customer" : { "customerID" : "5366041269806291704107" } },
"recipientInformation" : { "customer" : { "customerID" : "5366041269806291704107" },
"tokenizedCard" : { "expirationYear" : "2022", "number" : "5366041269806291704107",
"securityCode" :
"000", "expirationMonth" : "01", "type" : "001", "transactionType" : "1"
} } }
2. Here is the response body:
ResponseBody: { "clientReferenceInformation" : { "code" : "6280401" }, "errorInformation" : { "reason" : "INVALID_ACCOUNT", "message" : "Decline - Invalid account number" }, "id" : "5366041860956333603003", "status" : "DECLINED", "_links" : { "self" : { "href" : "/pts/v2/payments/5366041860956333603003", "method" : "GET" }, "authReversal" : { "href" : "/pts/v2/payments/5366041860956333603003/reversals", "method" : "POST" }, "capture" : { "href" : "/pts/v2/payments/5366041860956333603003/captures", "method" : "POST" }, "refund" : { "href" : "/pts/v2/payments/5366041860956333603003/refunds", "method" : "POST" }, "void" : { "href" : "/pts/v2/payments/5366041860956333603003/voids", "method" : "POST" } } }
The status code of the response is 201.
3. The request was not generated with a groovy script, but rather via the Visa Developer SDK, following the examples here: https://github.com/visa/SampleCode/tree/master/vdp-java/src/main/java/com/visa/vdp/utils
Specifically, I call VisaAPIClient.doXPayTokenRequest() using the endpoint:
https://sandbox.api.visa.com/cybersource/v2/payments?apikey={apikey}
with the same API key I use to generate tokens. Everything else is handled by the XPayHttpClient.
4. I generate payment tokens using v1of the Secure Acceptance Flex Token API and authorize the card using v2 of the CyberSource Payments REST API, as documented here: https://developer.visa.com/capabilities/cybersource/reference?next=cybersource__cybersource_flex_api...
Hello @rbrandenburg,
Per your response below you are generating payment tokens using v1of the Secure Acceptance Flex Token API. If you are a developer testing on v1 CyberSource APIs then this version was recently deprecated. You will need to move to v2 CyberSource APIs going forward. Could you please upgrade to V2 and try again.
Let me know if you have any questions.
Thank you,
Vaibhav
Thank you. I changed the URL for token generation to v2, but I noticed that when generating keys, the FlexService (from the SDK) is still using an HttpClient with the following v1 URL:
https://sandbox.api.visa.com/cybersource/payments/flex/v1/keys
I've looked into the documentation and I'm not sure where it gets this URL from-- it seems to have it as soon as I call FlexServiceFactory.createInstance(). Note that this is using new credentials created through my Visa Developer account. Is there something I need to do when creating these credentials to make them correspond to v2, or is there something in the SDK that I'm not seeing which lets me change the URL for generating keys? It looks like the version of the SDK I'm using (0.3.1) is the most recent one: https://search.maven.org/search?q=a:flex-server-sdk Note that I'm not looking to use MicroForm for this phase of implementation.
Can you tell me how to get a v2 FlexService using this SDK and/or get credentials that will let me initialize a v2 FlexService? Or will I need to make my own implementation of what the FlexService does?
I've started investigating this issue again and when I try to contact the V2 endpoint to generate a token, I get a 405 "Method not allowed" error. Do I need to update something on my Visa Developer account to use the V2 API? This also happens when I try to generate v2 keys using the same type of request on this endpoint:
https://sandbox.api.visa.com/cybersource/v2/payments/keys
What endpoint do I need to contact to get v2 keys and generate v2 payment profiles?
Hello guy,
I have the same issue and I don't find endpoin v2 to generateKey and Flex. I need to get v2 keys and generate v2 payment profiles.
Can you help me?