Taking the REST API out for a spin, and because my frame of reference is "classic API", specifically Express Checkout, I'm pretty much trying to "map" functionality.
Got things going, so this is more "conceptual" than technical..maybe someday this becomes a "wiki"...
Use case: payment_method:paypal
payer_info (Paypal user) is only available after an execute
in order to successfully (re)calculate totals to account for shipping and tax (based on shipping address), is the proper way of doing this via order (not sale) thereby allowing an authorization and capture after such details become available (to merchant)?
in other words, we don't have the classic GetExpressCheckoutDetails so this seems to be the path(?)
Based on this, and testing, can we assume the "maximum" of 115% (above order total) for the authorization call? Based on testing this seems to be true..otherwise "AUTHORIZATION_AMOUNT_LIMIT_EXCEEDED"
Update: In case you were wondering:
you can't update a payment resource. It's actually stated in the link (but I had to try).
you can't "re-execute" either
At this point the only thing that works so far is to authorize < 115%
The sum of the total open authorizations can’t exceed 115% or $75 (whichever is less) of the amount provided to PayPal when the order was created.
REF: https://developer.paypal.com/docs/integration/direct/create-process-order/
In docs, payer object has status defined as:
Status of the payer’s PayPal account. Currently supported with paypal payment_method only, but available for credit_card payment_method at a later date. Allowed values: VERIFIED or UNVERIFIED.
It doesn't seem to be returned in either sale nor order.
A secondary question therefore becomes, how do you "require" a verified PayPal user (is this now account level setting only - no API override)? See: flow_config
The other "missing" items are documented in the API release notes (e.g. fee).
Thanks!
Both order and authorize intent can be used to accomplish the flow (adjustments to authorization or capture) based on PayPal user info.
execute - returns PayPal payer_info - e.g.
"payer_info": {
"email": "foo#noemail.com",
"first_name": "Ed",
"last_name": "SF",
"payer_id": "ABCDEFG",
"shipping_address": {
"recipient_name": "Ed SF",
"line1": "111 Some street",
"city": "San Francisco",
"country_code": "US",
"postal_code": "94111",
"state": "CA"
}
}
Based on the above info, if there are any adjustments needed (i.e. sales tax, shipping),
order can be authorized for the additional amount* (and subsequently captured)
authorization can be captured for the additional amount*
*additional amount can’t exceed 115% or $75 (whichever is less) of the original order or authorization, otherwise, AUTHORIZATION_AMOUNT_LIMIT_EXCEEDED and CAPTURE_AMOUNT_LIMIT_EXCEEDED errors are raised respectively.
This is displayed to the user when a capture greater than the orginal authorization is made:
As far as I can tell, there isn't a similar message for an order (with adjusted amounts) - the additional authorization amount is displayed in the transaction details (only).
Related
I was helping a customer figure out an issue and creating test invoices in the sandbox.
After the 4th one I started getting this error:
{
"name": "BUSINESS_ERROR",
"message": "Number is too long.",
"information_link":
"https://developer.paypal.com/docs/api/invoicing/#errors",
"debug_id": "2ca1d32e1fed3"
}
What number is too long? I've tried looking through all the info and nothing appears too long our out of spec.
Hopefully somoene at Paypal can use the debug ID to track this. This test program has worked without issue for months.
So, after dealing with PayPal support the number that is too long was the invoice number.
When I started my testing in the sandbox I always had PayPal auto-generate the invoice number. It gave something like:
INV2-UR7F-35N45-DGQZ-BYDE
So, after a few tests, the invoice number was incremented (by PayPal) and eventually reached:
INV2-UR7F-35N99-DGQZ-BYDE
Now, on one more call the invoice would be incremented to:
INV2-UR7F-35N100-DGQZ-BYDE
Which is 26 characters, and the maximum length for invoice number is 25.
The solution? I was told to use smaller invoice numbers. ;)
I feel this is a possible bug in the auto-incrementation of the PayPal Invoice, but I am posting this so when others run into this they know what to do.
What I did was in my sandbox account call the Create Invoice Draft API with an invoice number like "Test001" so that there will be plenty of increments left in the invoice number. After that call there should be no need to supply an invoice number, at least for a very long time.
A credit card account (Account) can belong to multiple customers and One customer (Customer) can own multiple credit card accounts. I need to design REST API(s) which can return all accounts owned by a customer. The account number is coming from a manual input by an end user like a service rep into a freeform text box. Following is a constraint though
End consumers/developers know only account number & have no knowledge of customer id (unique identifier of a customer) upfront so to retrieve a list of accounts belonging to a customer -
1.1 find the customer owning the account in question
1.2 then find all the accounts owned by a customer.
I can think of couple of options but feel either they will make interaction chattier or may not be restful.
Only GET scenario has been discussed in below options
Option 1
Ideal way to interact with two separate resources but makes interaction very chatty and will put undue load on the system. Two calls everytime to know all accounts owned by a customer. So 20 Million calls/day in SOAP/RPC will become 40 million calls in REST.
/accounts/{account_nbr}/customers --> returns a list of customers for a specific account
/customers/{customer_id}/accounts --> returns a list of accounts for a customer
Option 2
I don't think this will be restful because query parameter is supposed to be used for identifying a resource in a non-hiearchical data
/customers/accounts?account_nbr = XXXX
Option 3
This option indicates that a list of accounts linked to account_nbr is being returned which is not right because list of accounts are linked to a customer
/accounts/{account_nbr}/linked_accounts
Option 4
Term the relationship between customer and an account as a new type of resource. Its trying to indicate get a list of customer to account relationships and identify specific instance where an account in customer_account_relationships has a value of XXXX.
/customer_account_relationships?account_nbr=XXXX or
Which of the above option, if any, is close to being restful representation? Is there any other way to design this interface?
EDIT
Expected response
{
"customerName" : "Bob",
"customerId" : 1234,
"listOfAccounts": [
{
"accountNbr" : "abcd"
"accountType": "creditcard"
},
{
"accountNbr" : "qrst"
"accountType": "creditcard"
}
]
}
You correctly rejected the first three options. I see two reasonable choices for you. One is to go with option 4:
GET /customer-summaries?account-number=<account-number>
The other is to just make /accounts top-level and do essentially the same thing:
GET /accounts?same-owner-as-account=<account-number>
In the former case, you'd get an instance of your resource above. In the second, you'd just get a list of accounts, each of which presumably has a link to the account owner. It's up to you as to which better suits your use case.
Note that option 4 may return multiple records if there are multiple owners for the same account. That's a common situation for married couples.
Does the Uber API offered "Uber Pool" ride type when we requests price / time estimates? Also, when a ride is coming, do we have access to a phone number in order to text the driver?
This isn't so much of an API issue as it is a feature question / request that a lot of our users wanted. I contacted Uber's support team via email and they told me to post anything API related in StackOverflow...
Does the Uber API offered "Uber Pool" ride type when we requests price / time estimates?
According to the GET /v1/products API endpoint documentation:
Some Products, such as experiments or promotions such as UberPOOL and UberFRESH, will not be returned by this endpoint.
Therefore, UberPOOL products are not avaliable through the Uber API.
Also, when a ride is coming, do we have access to a phone number in order to text the driver?
After you make a ride request using the POST /v1/requests API endpoint the first state the ride will be in is the processing state, to which you'll receive a response similar to:
Status-Code: 202 OK
{
"request_id": "852b8fdd-4369-4659-9628-e122662ad257",
"status": "processing",
"vehicle": null,
"driver": null,
"location": null,
"eta": 5,
"surge_multiplier": null
}
And as you can see you don't have access to any driver information in this state.
Then, as per the life cycle of a request, the request flow needs to move from the processing state to the accepted state, once a driver accepts your request.
The accepted state is the first state where you have access to driver details by either calling the GET /v1/requests/current or GET /v1/requests/{request_id} API endpoints.
You can know when the status changes either via a callback on your webhook or by polling at a 3-5 seconds interval one of the above Uber API endpoints to get the current status.
The HTTP response you receive after making one of the above HTTP requests looks something like this:
{
"request_id":"852b8fdd-4369-4659-9628-e122662ad257",
"status":"accepted",
"location":{
"latitude":37.7886532015,
"longitude":-122.3961987534,
"bearing":135
},
"pickup":{
"latitude":37.7872486012,
"longitude":-122.4026315287,
"eta":5
},
"destination":{
"latitude":37.7766874,
"longitude":-122.394857,
"eta":19
},
"driver": {
"phone_number": "(555)555-5555",
"rating": 5,
"picture_url": "https:\/\/d1w2poirtb3as9.cloudfront.net\/img.jpeg",
"name": "Bob"
},
"vehicle":{
"make": "Bugatti",
"model": "Veyron",
"license_plate": "I<3Uber",
"picture_url": "https:\/\/d1w2poirtb3as9.cloudfront.net\/car.jpeg"
},
"surge_multiplier":1.0,
"eta": 5
}
At this point you have access to the driver's phone number which you can use to call or text.
For Every PaypPal interaction we Do:
1.SetExpressCheckoutReq
2.GetExpressCheckoutDetailsReq
3.DoExpressCheckOutPaymentReq
I do create a billing agreement first and only on scheduled/subsequent orders we use this billing agreement for reference transaction.
Our Issue is:
With a new PayPal account (testpaypal#abc.com) DoExpressCheckoutPaymentReq failed for CITY = SuttonsBay, with the address validation error “10736” (Shipping Address Invalid City State Postal Code) for a user (USER A). And this was corrected in the subsequent request as Suttons bay.
But the same PayPal account(testpaypal#abc.com ) used for the second time with a different user (USER B) on the site, DoExpressCheckoutPaymentReq call succeeds for the wrong CITY = SuttonsBay and allows us to complete the order.
It is to be noted that on all scheduled order of the user, we use the DoReferenceTransactionReq, which has strict validation and this fails every time, esp. for the second scenario described above.
I would like to know why there are inconsistencies in Shipping address validation for DoExpressCheckoutPayment. It is because of this difference that our scheduled orders fails (as described in scenario 2 that allows incorrect address)
Do we any way to have strict Validation in DoExpressChecOutPayment - which solves our purpose?
I am testing MIGS Virtual Payment Client on a test account. When I select payment, I am directed to the Payment Server page where I can choose between Visa and MasterCard. I have been given the following test data in the MIGS manual:
I use 123 as CSC value. However, the transaction always fail with
vpc_VerStatus=E
vpc_TxnResponseCode=2
vpc_Message=Declined //for Visa
vpc_Message=The+card+holder+was+not+authorised.+This+is+used+in+3-D+Secure+Authentication. //for MasterCard
By the way, if I select MasterCard, I am prompted "Please enter your OSID or the last 5 digits of your NAB ID" and a Credit Limit. I use OSID with value 123456 and Credit Limit 10000 respectively. (These are values I entered by myself as I was not given information what to input there).
I had a look at this Commonwealth bank and MIGS Virtual Payment Client error code but it does not solve my problem.
Any help why the transaction is being declined?
Okay, there's a handful of things here you need to understand/check out.
1. Ensure the transaction value ends in $xyz.00 or it will always decline
MIGS behaves differently in TEST and PROD. In TEST, MIGS uses the "cents" portion of your test transactions to determine what response code to return, NOT whether you have correctly provided the necessary data for the transaction. These cents values are as follows:
$ XXX.00 returns "0 Transaction approved"
$ XXX.10 returns "1 Transaction could not be processed"
$ XXX.05 returns "2 Transaction declined - contact issuing bank"
$ XXX.68 returns "3 No reply from Processing Host"
$ XXX.33 returns "4 Card has expired"
$ XXX.51 returns "5 Insufficient credit"
2. Disable 3-D Secure
It looks like you're also getting caught by 3DSECURE, also known as "Verified by Visa" and "Mastercard SecureCode". Call your acquirer/bank and ask them to disable this in TEST and Prod. Why? Invariably when this goes live, your customers will see a screen they are not expecting that asks for more information and then either pick up the phone and ask you to "fix it" or (even worse) leave your store thinking it's fraud.
Because 3-D secure has such low takeup, even most bank support staff don't know about it. Just today I had one of my clients call me about this "issue". One of their customers had called their card issuer to enquire as to what this "Verified by Visa" screen was. The bank (a major Australian bank) helpfully told them it was probably fraud and to not buy anything from that site.
3-D secure has such low penetration in Australia I'd suggest the only outcome of having it enabled is to reduce sales. Don't use it.