How can I test flagged transaction response in test environment in Checkout.com - paypal

I am using Checkout.com for payment processing. I want to test flagged transaction response in a test environment.
How can I get this response in test mode?

Flagging a transaction is an action that is taken by a Risk Rule in Checkout.com
To be able to flag a transaction you simply need to set a risk rule in your Checkout.com Hub and trigger this risk rule in your payment request.
For example, you can set up a "threshold" risk rule that will flag a transaction if it exceeds (or it's bellow) a certain amount.
After setting up this, sending a payment request with a value that will trigger the risk rule, will result in a flagged response from the API.
You can also see some sample responses in the API Reference of Checkout.com
Here is a sample:
{
"id": "pay_jf7xoknmva3upbatzkiqcwvkea",
"action_id": "act_jf7xoknmva3upbatzkiqcwvkea",
"amount": 20000,
"currency": "USD",
"approved": true,
"status": "Authorized",
"auth_code": "290947",
"eci": "05",
"scheme_id": "638284745624527",
"response_code": "10000",
"response_summary": "Approved",
"risk": {
"flagged": true
},
"source": {
// dynamic based on your source
},
"customer": {
"id": "cus_vh2hq53yioouvg3etkuw2xdhcu",
"name": "Sarah Mitchell"
},
"processed_on": "2019-06-25T18:27:10Z",
"reference": "ORD-5023-4E89",
"processing": {
"acquirer_transaction_id": "8138182777",
"retrieval_reference_number": "000290947597"
},
"_links": {
"self": {
"href": "https://api.sandbox.checkout.com/payments/pay_jf7xoknmva3upbatzkiqcwvkea"
},
"actions": {
"href": "https://api.sandbox.checkout.com/payments/pay_jf7xoknmva3upbatzkiqcwvkea/actions"
},
"capture": {
"href": "https://api.sandbox.checkout.com/payments/pay_jf7xoknmva3upbatzkiqcwvkea/captures"
},
"void": {
"href": "https://api.sandbox.checkout.com/payments/pay_jf7xoknmva3upbatzkiqcwvkea/voids"
}
}
}
Notice the:
"risk": {
"flagged": true
},

Related

How to properly pass the session_id to GA4 via Measurement protocol

GA4 purchase events are sent from client server via measurement protocol. But there is no session_id parameter in the queries, because of that source and medium is lost. We tried to pass the session_id parameter in MP request, but no data were received.
Example of submitted request:
{
"timestamp_micros": "1664522406546590",
"non_personalized_ads": false,
"events": [
{
"name": "purchase_balance_top_up",
"params": {
"user_id": "11111111",
"crm_id": "11111111",
"balance": 990,
"payment_method": "paymore"
}
}
],
"client_id": "1119492379.1652295143",
"session_id": "1664522264",
"user_id": "11111111"
}
Attaching a screenshot of the raw data from BigQuery on events sent by MP.
Screenshot of the raw data from BigQuery
Help, how to properly pass the session_id? Or how to make sure that events don't lose source param?
We found a solution to the problem. It's simple. The parameter "session_id" must be passed inside the array "params" of the event.
Here is an example of the correct event data array to be sent via measurement protocol:
{
"timestamp_micros": "1664522406546590",
"non_personalized_ads": false,
"events": [
{
"name": "purchase_balance_top_up",
"params": {
"user_id": "11111111",
"crm_id": "11111111",
"balance": 990,
"payment_method": "paymore",
"session_id": "1664522264"
}
}
],
"client_id": "1119492379.1652295143",
"user_id": "11111111"
}
Actually we are sending purchase events similarly with such request:
{
"client_id": "xxx.xxx",
"user_id" : "xxxx",
"non_personalized_ads": false,
"user_properties": {
"user_id_dimension": {
"value": "xxxx"
}
},
"events": [{
"name": "purchase",
"params": {
"currency": "USD",
"transaction_id": "T_12345",
"value": 12.21,
"engagement_time_msec": 10,
"session_id": "XXXXXXXXXX",
"items": [
{
"item_name": "Top-up"
}
]
}
}]
}
but we are not sending timestamp_micros. And we send 'user_id_dimension' as user property with the same value as 'user_id' parameter to observe user id further in Exploration reports. We've created user-scoped custom dimension in GA4 interface with dimension name User ID and this user property 'user_id_dimension'. Everything works

PayPal Invoicing API - VALIDATION_ERROR

I am developing an application that communicates with PayPal's API to create invoices.
This is my Request Body:
{
"detail": {
"currency_code": "USD",
"note": "Thank you for using my services!"
},
"invoicer": {
"name": {
"given_name": "Shreyas",
"surname": "Ayyengar"
},
"email_address": "{email}",
"website": "{website}"
},
"primary_recipients": [
{
"billing_info": {
"email_address": "{client_email}"
}
}
],
"items": [
{
"name": "{invoice_name}",
"description": "{invoice_description}",
"quantity": "1",
"unit_amount": {
"currency_code": "USD",
"value": "{invoice_amount}"
},
"tax": {
"name": "PayPal Service Tax",
"percent": "7.25"
}
}
],
"configuration": {
"partial_payment": {
"allow_partial_payment": false
},
"allow_tip": true
}
}
While there are placeholders like: {client_email}, I can guarantee that they are replacing properly and as expected.
However I'm thrown a VALIDATION_ERROR which I am not able to understand: {"name":"VALIDATION_ERROR","message":"Invalid request - see details.","information_link":"https://developer.paypal.com/docs/api/invoicing/#errors","details":[{"field":"merchant_info","issue":"cannot be null."},{"field":"items[0].unit_price","issue":"null"}]}
From what I can minimally understand, this error says that I have missing information like Items[].unit_price and merchant_info however I have no idea where this is supposed to be in my Request Body. I am following the direct documentationhere but I cannot see anything that mentions unit_price or merchant_info.
Submit your request to the correct API endpoint, https://api-m.sandbox.paypal.com/v2/invoicing/invoices
Note the major version number. See the Invoicing API reference for details.

no webhook calls with subscription in paypal sandbox mode

With php and curl i create billing plans, subscriptions, get the paypal link and proceed to the payment. Everything works and i get the following webhook calls :
Billing plan created
Billing subscription created
Billing subscription activated
Paiement sale completed
So far so good. The problem is that i specified the subscription to a renewal of 1 DAY so i could check what happens when a new regular payment arrives... and nothing.
I don't know if the sandbox does not implement a real subscription with all the correct webhook callback of if i'm doing something wrong. I would be pretty pissed to be forece to develop that in production mode !
Any ideas ?
Any ideas how to test the recurring payment ?
Here is the data i get from paypal API when i call billing_subscription:
You can view it properly on https://jsoneditoronline.org/
{
"billing_cycles": [
{
"frequency": {
"Interval_count": 1,
"interval_unit": "DAY"
},
"pricing_scheme": {
"create_time": "2021-08-11T13:47:42Z",
"fixed_price": {
"currency_code": "EUR",
"value": "2.0"
},
"update_time": "2021-08-11T13:47:42Z",
"version": 1
},
"sequence": 1,
"tenure_type": "REGULAR",
"total_cycles": 120
}
],
"create_time": "2021-08-11T13:47:42Z",
"description": "offre Basic TEST avec un debit tous les jours",
"id": "P-8AF2870811319631YMEJ5J7Q",
"links": [
{
"encType": "application/json",
"href": "https://api.sandbox.paypal.com/v1/billing/plans/P-8AF2870811319631YMEJ5J7Q",
"method": "GET",
"rel": "self"
},
{
"encType": "application/json",
"href": "https://api.sandbox.paypal.com/v1/billing/plans/P-8AF2870811319631YMEJ5J7Q",
"method": "PATCH",
"rel": "edit"
},
{
"encType": "application/json",
"href": "https://api.sandbox.paypal.com/v1/billing/plans/P-8AF2870811319631YMEJ5J7Q/deactivate",
"method": "POST",
"rel": "self"
}
],
"name": "Offre Basic TEST JOUR PAR JOUR",
"payment_preferences": {
"auto_bill_outstanding": true,
"payment_failure_threshold": 3,
"service_type": "PREPAID",
"setup_fee": {
"currency_code": "EUR",
"value": "0.0"
},
"setup_fee_failure_action": "CONTINUE"
},
"product_id": "abonnement-test-basic",
"quantity_supported": false,
"status": "ACTIVE",
"taxes": {
"inclusive": false,
"percentage": "20.0"
},
"update_time": "2021-08-11T13:47:42Z",
"usage_type": "LICENSED"
}
Problem solved (sort-of...)
In production mode, when a recurring paiement is done on a subscription a webhook is called with the event : PAYMENT.SALE.COMPLETED
In sandbox mode, the event is either not sent, either randomly sent days later after when it's supposed to be.

Cannot capture sandbox PayPal payment

I am currently trying the Orders API of PayPal using Postman, but cannot capture any payment.
For now, I could get the access token, set it to a collection variable, then created orders using (note the access token is set in the Authorization tab):
POST https://api-m.sandbox.paypal.com/v2/checkout/orders
Body:
{
"intent": "CAPTURE",
"purchase_units": [
{
"amount": {
"currency_code": "USD",
"value": "10.00"
}
}
]
}
The request was successful with response body:
{
"id": "<random-id>",
"status": "CREATED",
"links": [
{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/<random-id>",
"rel": "self",
"method": "GET"
},
{
"href": "https://www.sandbox.paypal.com/checkoutnow?token=<random-id>",
"rel": "approve",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/<random-id>",
"rel": "update",
"method": "PATCH"
},
{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/<random-id>/capture",
"rel": "capture",
"method": "POST"
}
]
}
Then I proceeded to rel:approve's link using a browser https://www.sandbox.paypal.com/checkoutnow?token=<random-id> and signed in with my sandbox account. It shows me the usual payment window but when I pressed the "Continue" button, it tried to redirect to the return page but instead, refreshed the page itself.
When I tryed to check the order using rel:self's link: GET https://api.sandbox.paypal.com/v2/checkout/orders/<random-id>. It correctly showed the sandbox account's shipping details (name and address), but the status remained CREATED (not APPROVED or COMPLETED):
{
"id": "<random-id>",
"intent": "CAPTURE",
"status": "CREATED",
"purchase_units": [
{
"reference_id": "default",
"amount": {
"currency_code": "USD",
"value": "10.00"
},
"payee": {
"email_address": "<payee-email>",
"merchant_id": "<payee-id>"
},
"shipping": {
"name": {
"full_name": "<payer-name>"
},
"address": {
"address_line_1": "<payer-address-1>",
"address_line_2": "<payer-address-2>",
"admin_area_2": "<payer-address-3>",
"admin_area_1": "<payer-address-4>",
"postal_code": "<payer-address-5>",
"country_code": "<payer-address-6>"
}
}
}
],
"create_time": "<time-of-post-request>",
"links": [
{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/<random-id>",
"rel": "self",
"method": "GET"
},
{
"href": "https://www.sandbox.paypal.com/checkoutnow?token=<random-id>",
"rel": "approve",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/<random-id>",
"rel": "update",
"method": "PATCH"
},
{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/<random-id>/capture",
"rel": "capture",
"method": "POST"
}
]
}
When I tried to capture the payment using rel:caputure's link: POST https://api.sandbox.paypal.com/v2/checkout/orders/<random-id>/capture with header Content Type: application/json and empty body, it said "payer has not approved the Order for payment", despite I getting the shipping details from the GET request before:
{
"name": "UNPROCESSABLE_ENTITY",
"details": [
{
"issue": "ORDER_NOT_APPROVED",
"description": "Payer has not yet approved the Order for payment. Please redirect the payer to the 'rel':'approve' url returned as part of the HATEOAS links within the Create Order call or provide a valid payment_source in the request."
}
],
"message": "The requested action could not be performed, semantically incorrect, or failed business validation.",
"debug_id": "6a10ea489ffce",
"links": [
{
"href": "https://developer.paypal.com/docs/api/orders/v2/#error-ORDER_NOT_APPROVED",
"rel": "information_link",
"method": "GET"
}
]
}
I have three questions:
Was I using the Orders API correctly? Did I miss some HTTP requests and/or some crucial steps?
I had the return URL set for my sandbox application, why did the payment page not redirect me but instead refreshed itself? Did I miss some setup beforehand?
Why did I fail to capture the payment like above?
P.S. After some digging I think I might be missing the authorize payment step but I have no idea how to do it. (Client-side request? Server-side request?)
I proceeded to rel:approve's link .. when I pressed the "Continue" button, it tried to redirect to the return page but instead, refreshed the page itself.
You did not specify a return_url , so there is nowhere to return to. Refreshing is all that can be done.
What you should do is not redirect to an approval URL, and integrate with no redirects. For this make two routes on your server, one for 'Create Order' and one for 'Capture Order', documented here. These routes should return only JSON data (no HTML or text). The latter one should (on success) store the payment details in your database before it does the return (particularly purchase_units[0].payments.captures[0].id, the PayPal transaction ID)
Pair those two routes with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server
I was also having trouble with this issue, I solved it by expanding the request body, much like #preston-phx said, with the return URL, and it looked something like this:
{
"intent": "CAPTURE",
"payer": {
"email_address": requestBody.payer_email
},
"purchase_units": [{
"amount": {
"currency_code": "USD",
"value": requestBody.amount
},
"payee": {
"email_address": requestBody.payee_email
},
"payment_instruction": {
"disbursement_mode": "INSTANT", // can be INSTANT or DELAYED
"platform_fees": [
{
"amount": {
"currency_code": "USD",
"value": calculateFeesFromAmount(requestBody.amount)
}
}
]
}
}],
"redirect_urls": {
"return_url": "https://example.com/paypalpay/order/approved",
"cancel_url": "https://example.com/paypalpay/order/cancelled"
},
"application_context": {
"brand_name": "Header for payment page",
"locale": "en-US",
"landing_page": "BILLING", // can be NO_PREFERENCE, LOGIN, BILLING
"shipping_preference": "NO_SHIPPING" // because I didn't want shipping info on the page,
"user_action": "PAY_NOW", // Button name, can be PAY_NOW or CONTINUE
"return_url": "https://example.com/paypalpay/order/approved",
"cancel_url": "https://example.com/paypalpay/order/cancelled"
}
}
This also helped me customise the payment page to an extent. I hope Paypal folks include these in the docs at the correct places, most of devs have to dig through a lot of documentation to create an extensive, usable request body.

No token in request - Account Linking with new Actions SDK

I am building an action with the new Actions Builder and everything is going pretty smoothly. I just setup account linking and can successfully link my account, however, once I do link my account there is no token included in the subsequent requests for me to use, even though the account linking status is in the request as "LINKED". Can anyone shed any light on why I am not seeing a token?
For reference, here is a version of one of my requests.
{
"requestJson": {
"handler": {
"name": "main"
},
"intent": {
"name": "actions.intent.MAIN",
"params": {},
"query": "Talk to my new app"
},
"scene": {
"name": "actions.scene.START_CONVERSATION",
"slotFillingStatus": "UNSPECIFIED",
"slots": {},
"next": {
"name": "ListPrompt"
}
},
"session": {
"id": "ABwppHE7M6NS8KdyjljEptrtZZ5GkE3qDdaiwjYbL9ehrA-t_c-ZsCrZ_WhN0ZTG5lXXXXXXhU6Im5vgeSwow",
"params": {},
"typeOverrides": [],
"languageCode": ""
},
"user": {
"locale": "en-US",
"params": {},
"accountLinkingStatus": "LINKED",
"verificationStatus": "VERIFIED",
"packageEntitlements": [],
"lastSeenTime": "2020-07-13T12:02:42Z"
},
"home": {
"params": {}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO"
]
}
}
}
The Google docs for the Account Linking with the new Actions Builder have now been updated with additional information. The token is now provided within the headers of the incoming request. Details of how to find and decode this can be found at https://developers.google.com/assistant/identity/google-sign-in#handle_data_access_requests