My sandbox account return this error when creating a payout
{
"name": "PAYOUT_NOT_AVAILABLE",
"message": "You live in a country that is not allowed to send this payout.",
}
This error is not listed in https://developer.paypal.com/docs/api/payments.payouts-batch/#errors
The account is configured in México (MX) and the official documentation includes MX in the payouts docs.
Am I missing something? Can't find any doc that excludes specific countries.
Just some exceptions for Argentina, Brazil and Malaysia.
It also defiens Mexican currency in the features
https://developer.paypal.com/docs/payouts/#payouts-features
I happened to find a similar endpoint but the weird thing is that it's not listed in the main APIs menu but it seems to be working, for reference check:
https://developer.paypal.com/docs/payouts/test
Update: it seems to be related to the test data that's used in the note field, even if using batch payouts the following changed the result status:
{
"sender_batch_header": {
"sender_batch_id": "Payouts_2018_100007",
"email_subject": "You have a payout!",
"email_message": "You have received a payout! Thanks for using our service!"
},
"items":[
{
"recipient_type": "EMAIL",
"amount": {
"value": "500",
"currency": "MXN"
},
"note": "POSPYO001",
"sender_item_id": "201403140001",
"receiver": "ss36#business.example.com",
"alternate_notification_method": {
"phone": {
"country_code": "52",
"national_number": "4491110560"
}
},
"notification_language": "sp-SP"
}
]
}
A single payout looks like this:
{
"sender_payout_header":
{
"sender_batch_id": "1524086406556",
"email_subject": "This email is related to simulation"
},
"items": [
{
"recipient_type": "EMAIL",
"receiver": "payouts-simulator-receiver#paypal.com",
"note": "POSPYO001",
"sender_item_id": "15240864065560",
"amount":
{
"currency": "USD",
"value": "1.00"
}
}]
}
I was having the same issue and it was because my country(India) name is present in supported countries list of PayPal but i got to know about PayPal Commerce Platform availability where it is not supporting India. Check below link
https://developer.paypal.com/docs/api/reference/country-codes/?mark=countries#paypal-commerce-platform-availability
My work is only on sandbox account of paypal for testing so i simply created new test account of country US.
Possibly your paypal account is from any country listed in above link. Please check country of your main paypal account.
Related
I've been working on a web-based system using PHP. The system is linking to the payment gateway using API and webhooks for payment notification. I've worked on everything else but webhooks are foreign to me. I've subscribed to webhooks and the payment gateway is supposed to send in JSON via the url submitted when creating webhooks. Below is the sample JSON.
{
"topic": "buygoods_transaction_received",
"id": "2133dbfb-24b9-40fc-ae57-2d7559785760",
"created_at": "2020-10-22T10:43:20+03:00",
"event": {
"type": "Buygoods Transaction",
"resource": {
"id": "458712f-gr76y-24b9-40fc-ae57-2d35785760",
"amount": "100.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "OJM6Q1W84K",
"till_number": "000000",
"sender_phone_number": "+254999999999",
"origination_time": "2020-10-22T10:43:19+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": null
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/2133dbfb-24b9-40fc-ae57-2d7559785760",
"resource": "https://sandbox.kopokopo.com/financial_transaction/458712f-gr76y-24b9-40fc-ae57-2d35785760"
}
}
I need to capture some fields like OJM6Q1W84K,100.0 etc and store them into my db. How do I capture the JSON? The rest will be easy for me once I figure out that one. Thanks guys.
I'm new with STRIPE, and I've been reading the documentation for STRIPE, and was task to create a list of payouts to a connected account (type is standard). Also, I have to show the details, under those PAYOUT, all the payments included in it.
However I can't see any relation to PAYOUTS with PAYMENT INTENTS/CHARGES, is it possible to know all those payments included in the PAYOUTS ? We are creating STANDARD connect accounts for our users.
I had the same challenge, and had to go thru 4 supporters, tell my needs over and over again, before i finally got the right hint and could complete my checks and cron jobs. I provide my solution here to save others the same experience:
$po = 'po_sadfahk.....'; // payout id (i do a loop of payouts)
\Stripe\Stripe::setApiKey($stripeSecretKey);
$balanceTransactions = \Stripe\BalanceTransaction::all([
'payout' => "$po",
'type' => 'charge',
'limit' => 100, // default is 10, but a payout can have more pi's
'expand' => ['data.source'],
]);
foreach ($balanceTransactions->data as $txn) {
// my invoice id is added in description when creating the payment intent
echo "Invoice: {$txn->description}\n";
echo "Created: {$txn->created}\n";
echo "Available: {$txn->available_on}\n";
// in source we find the pi_id, amount and currency for each payment intent
$charge = $txn->source;
echo "pi: {$charge->payment_intent}\n";
$amount = $charge->amount/100;
echo "$amount {$charge->currency}\n";
}
Output (cropped to relevant data):
{
"object": "list",
"data": [
{
"id": "txn_1ISOaSGqFEoKRtad...",
"object": "balance_transaction",
"amount": 25000,
"available_on": 1615680000,
"created": 1615131127,
"currency": "dkk",
"description": "Invoice 44",
...
"fee": 530,
"fee_details": [
{
"amount": 530,
"application": null,
"currency": "dkk",
"description": "Stripe processing fees",
"type": "stripe_fee"
}
],
...
"source": {
"id": "ch_1ISOaRGqFEoKR...",
"object": "charge",
"amount": 25000,
...
"paid": true,
"payment_intent": "pi_1ISOa3GqFE...", // here we go!
"payment_method": "pm_1ISOaRGqFE...",
"payment_method_details": {
"card": {
"brand": "visa",
...
},
"type": "card"
},
...
},
"status": "available",
"type": "charge"
}
],
"has_more": false,
"url": "/v1/balance_transactions"
}
Kudos to Kim for his answer. I also went through a number of supporters in Stripe to no avail. His post sorted me out.
The code below is a mere Python 3.10 translation from Kim's code above
po = 'po_<some_payment_id>'
balanceTransactions = stripe.BalanceTransaction.list(
payout=po,
type='charge',
limit=100,
expand=['data.source']
)
for txn in balanceTransactions.data:
print("Invoice: {0}".format(txn.description))
print("Created: {0}".format(txn.created))
print("Available: {0}".format(txn.available_on))
charge = txn.source
print("pi: {0}".format(charge.payment_intent))
amount = charge.amount/100
print("{0} {1}".format(amount, charge.currency))
I'm not sure you'll have that access for a Standard Account, but if it you do, you'll be able to list all of the Balance Transactions associated with that Payout, which will have a reference to the Payment Intent in the source field for any Payment Intents.
i'm using Paypal PHP SDK (in Laravel) to prepare a payment. At the moment, that payment looks like this:
{
"intent":"sale",
"payer":{
"payment_method":"paypal"
},
"redirect_urls":{
"return_url":"http://website.lab/payment/paypal/success",
"cancel_url":"http://website.lab/payment/paypal/cancel"
},
"transactions":[
{
"amount":{
"currency":"EUR",
"total":"223",
"details":{
"shipping":"0",
"subtotal":"273"
}
},
"description":"...",
"item_list":{
"items":[
{
"name":"product 8",
"currency":"EUR",
"quantity":21,
"sku":"w9",
"price":"13.00"
}
],
"shipping_address":{
"city":"...",
"postal_code":"...",
"country_code":"...",
"recipient_name":"...",
"line1":"..."
}
}
}
]
}
As you can see there are 50€ missing from the total to the subtotal and this cause this error
400{"name":"VALIDATION_ERROR","details":[{"field":"transactions[0].amount","issue":"Transaction amount details (subtotal, tax, shipping) must add up to specified amount total"}],"message":"Invalid request - see details","information_link":"https://developer.paypal.com/docs/api/payments/#errors","debug_id":"91d27597e954"}
Now looking to the Paypal SDK i'm not able to find any sort of method/Object that can tell Paypal to add a discount to the subtotal.
Any help will be appreciate, i really can't find any resource on the web that can solve this problem
You can add an item to your "item_list" with a negative value to the transaction:
{
"name": "Discount",
"price": "-50",
"currency": "EUR",
"quantity": "1"
}
I am developing an e-commerce mobiloe application using magento 2 rest apis only.This is the flow for making the REST API calls for order placement.
1.Create a cart
api -->{{url}}/index.php/rest/V1/carts/mine
This api will return a unique cart id
2.Add products to cart
api --> {{url}}/index.php/rest/V1/carts/mine/items
body ->
{
"cart_item": {
"quote_id": cartId,
"sku": skuName,
"qty": 1
}
}
3. Estimate Shipping Methods
url --> {{url}}/index.php/rest/V1/carts/mine/estimate-shipping-methods
body ->
{
"address": {
"region": "Trivandrum",
"region_id": 12,
"region_code": "CA",
"country_id": "IN",
"street": [
"Amstor house",
"Eramam"
],
"telephone": "5656565454",
"postcode": "670390",
"city": "Kazhakuttam",
"firstname": "Peter",
"lastname": "K",
"same_as_billing": 0,
"save_in_address_book": 0
}
}
This will return all possible shipping methods based on shipping address.In my case the result is
[
{
"carrier_code": "freeshipping",
"method_code": "freeshipping",
"carrier_title": "Free Shipping",
"method_title": "Free",
"amount": 0,
"base_amount": 0,
"available": true,
"error_message": "",
"price_excl_tax": 0,
"price_incl_tax": 0
}
]
4)Save shipping information
url --> {{url}}/index.php/rest/V1/carts/mine/shipping-information
body data ->
{
"addressInformation": {
"shipping_address": {
"region": "Trivandrum",
"region_id": 12,
"region_code": "CA",
"country_id": "IN",
"street": [
"Amstor house",
"Eramam"
],
"telephone": "5656565454",
"postcode": "670390",
"city": "Kazhakuttam",
"firstname": "Peter",
"lastname": "K",
},
"billing_address": {
"region": "Trivandrum",
"region_id": 12,
"region_code": "CA",
"country_id": "IN",
"street": [
"Amstor house",
"Eramam"
],
"telephone": "5656565454",
"postcode": "670390",
"city": "Kazhakuttam",
"firstname": "Peter",
"lastname": "K",
},
"shipping_method_code": "freeshipping",
"shipping_carrier_code": "freeshipping"
}
}
This will return all possible payment methods. Here i am using paypal_express for payment.
5. Payment using paypal plugin
Here i will pay the amount using paypal cordova plugin.Also configured the IPN [{{url}}/paypal/ipn/]in paypal account
This api will return the following data,
{
"client": {
"environment": "sandbox",
"paypal_sdk_version": "2.14.4",
"platform": "Android",
"product_name": "PayPal-Android-SDK"
},
"response": {
"create_time": "2016-11-19T05:25:46Z",
"id": "PAY-5VS11410F5341972MLAX6ETA",
"intent": "sale",
"state": "approved"
},
"response_type": "payment"
}
5.Save payment and place order
url --> {{url}}/index.php/rest/V1/carts/mine/payment-information
data ->
{
"cartId": 3,
"billingAddress": {
"region": "Trivandrum",
"region_id": 12,
"region_code": "CA",
"country_id": "IN",
"street": [
"Amstor house",
"Eramam"
],
"telephone": "5656565454",
"postcode": "670390",
"city": "Kazhakuttam",
"firstname": "Peter",
"lastname": "K"
},
"paymentMethod": {
"method": "paypal_express"
}
}
But this api will returning
{
"message": "PayPal gateway has rejected request. Invalid token (#10410: Invalid token)."
}
Is there any api missing in the above flow for capturing payments.Please help me.
Paypal Express payment method doesn't support online capturing. There is no way to get a full order creation flow like on Checkout via Magento API interface. It is impossible to change the order state and process payments. As a workaround try the following:
Create a custom payment method
Enable for REST API only(Not on website checkout page)
While making payment using rest api use this method (after successful payment using you android/ios SDK)
After placing the order make send transaction id(PAY-xxxxx) return by paypal sdk payment to save trasaction.(tell your server side tio implement this call).
I am writting a complete atrticle regarding this step by step. I will let you know when it is done.
Place Order by PayPal Rest API
For the Place order by the Paypal rest API, you need an active cart with shipping and billing address
By default, we need to follow the few setups for placing the order
• Step 1. Create an empty cart
• Step 2. Add products to the cart
• Step 3. Set the shipping address
• Step 4. Set billing address
• Step 5. Set the delivery method
• Step 6. Apply a coupon (if you have)
• Step 7. Set the payment method
• Step 8. Place order
After steps 6 follow below APIs
We need to call the below APIs one by one for placing the order with Paypal
Create Paypal Express Token
URL : {you website
url}/rest/default/V1/paypalapi/createpaypalexpresstoken
Method: POST
Set Bearer Token in the Hearer (if customer ) for the guest user no need to set it
Content-type : JSON
Body For guest users:
{
"cart_id":"5QWFYZdyccucvgD2QMLDCp5fhjmaH2xg",
"cancel_url":"cancel_url",
"return_url":"return_url"
}
Body For Customer user:
{
"cart_id": 22,
"cancel_url": "cancel_url",
"return_url": "return_url"
}
You will get the response like this :
[
{
"code": 200,
"token": "EC-4MD50688YD296870K",
"paypal_urls":{
"start": "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-4MD50688YD296870K&useraction=commit",
"edit": "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=continue&token=EC-4MD50688YD296870K"
}
}]
Explanation
you need to redirect the customer to the {start URL } and after making the payment, PayPal will redirect the user with two params in the redirect URL "payer_id" and "token" Both values you need to call in the below API
Set Payment Method On Cart
URL : {you website
url}/rest/default/V1/paypalapi/setpaymentmethodoncart
Method: POST
Set Bearer Token in the Hearer (if customer ) for the guest user no
need to set it
Content-type : JSON
Body For guest users:
{
"cart_id": "5QWFYZdyccucvgD2QMLDCp5fhjmaH2xg",
"payer_id": "9T3GV67ZSL378",
"token": "EC-4MD50688YD296870K",
"payment_method": "paypal_express"
}
Body For Customer user:
{
"cart_id": 22,
"payer_id": "9T3GV67ZSL378",
"token": "EC-4MD50688YD296870K",
"payment_method": "paypal_express",
"customer_id": 141
}
You will get the response like this :
[
{
"code": 200,
"selected_payment_method": {
"code": "paypal_express",
"title": "PayPal Express Checkout"
}
}
]
Place Order
URL : {you website url}/rest/default/V1/paypalapi/placeorder
Method: POST
Set Bearer Token in the Hearer (if customer ) for the guest user no
need to set it
Content-type : JSON
Body For guest users:
{ "cart_id": "5QWFYZdyccucvgD2QMLDCp5fhjmaH2xg" }
Body For Customer user:
{ "cart_id": 22, "customer_id": 141 }
You will get the response like this :
[ { "code": 200, "order_number": 000000142 } ]
Here is the link to the Paypal Rest API module
https://github.com/santosh-gaggle/paypal-rest-api
In case someone still looking the solution.
In the time I'm answering this, You will need to create a Magento 2 module to process the payment ID.
After you receive the response from in example Paypal android SDK.
Below is the JSON format that you can send to Magento endpoint :
for logged user : PUT /V1/carts/mine/order
for guest : PUT /V1/guest-carts/:cartId/order
Referrence : http://devdocs.magento.com/swagger
The "paypal_express_payment_payload" is just a custom attribute to hold the paypal payment response previously from android SDK.
{
"paymentMethod": {
"method": "paypal_express",
"additional_data": {
"paypal_express_payment_payload": "{\"create_time\":\"2017-06-15T23:13:52Z\",\"id\":\"PAY-2LB41725NU654612TLFBRIUQ\",\"intent\":\"sale\",\"state\":\"approved\"}"
}
}
}
To process the "paypal_express_payment_payload" data, you can implement a Interceptor in your Magento 2 module :
di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Paypal\Model\Express">
<plugin name="mymodule_magento_paypal_model_express_plugin"
type="Mycompanyorpersonal\Mymodule\Plugin\Paypal\Model\Express"
sortOrder="99999"
disabled="false" />
</type>
</config>
Mycompanyorpersonal\Mymodule\Plugin\Paypal\Model\Express.php
You can find the full PHP codes in my following gist : https://gist.github.com/feelinc/de817030e00adc7ff7001de1807c1835
If you use the below to run a post query replace runPostQuery with your curl request. this will pass a token that already has been successful to magento 2.
$payment['paymentMethod'] = ['method' =>'paypal_express',
'additional_data' => array (
'paypal_express_checkout_token' => $request->query->get('token'),
'paypal_express_checkout_redirect_required' => false,
'paypal_express_checkout_payer_id' => $request->query->get('PayerID')
)];
$completedPayment = $this->runPostQuery('carts/mine/payment-information', $headers, json_encode($payment));
You will need to create a plugin to add the last transaction id to the payment see the above comment, but the above payload to payment-information will allow you to get past _placeOrder function in Paypal\Model\Express.php
The paypal_express_checkout_token is the token passed back to the browser from paypal same as PayerId this allows to check the payment, which will return successful and not require a redirect, but is not the payment reference just the action token.
When i create an event with the graph api i need to specify the venue and i would like also to show the map.
I do
$fb_event['name'] = "THis is to test latitude";
$fb_event['description'] = "And longitude!!!!";
$fb_event['start_time'] = date( "c", Ai1ec_Facebook_Event::get_facebook_start_time($event->start));
$fb_event['location'] = "Where you want";
$fb_event['street'] = "Via andrea del sarto 9";
$fb_event['city'] = "Milan";
$fb_event['latitude'] = 45.444975793404;
$fb_event['longitude'] = 9.2119209654715;
$facebook = $this->facebook_instance_factory();
try {
$result = $facebook->api( "/me/events", "POST", $fb_event );
} catch (FacebookApiException $e) {
fb($e);
}
This produce this event which show the correct street and city, but no map. If i edit the event and save, the map "Magically" appears using the street and city correctly.
In any case latitude and longitude are ignored.
What am i doing wrong?
If you compare your two test events in the Graph API explorer you'll see that Event ID 239298922846828 does not have its latitude and longitude populated, while 245655182207213 does. I'm assuming 245655182207213 is an event you've edited.
Looking at your code, you seem to be doing everything as described in the documentation. However, I've found that what is described does not always work.
What I've been seeing is that events populated from within Facebook that occur at a known venue are no longer allowing you to specify an address. Instead all they save is a venue id within Facebook which you can then drill into to get the address, etc.
Take a look at one of my events. For this event, there is no way to edit the details of this location from within Facebook, nor does the event venue details get returned with an API call. I'm using the API to pull the event details to an external website. This change caused me days of frustration.
I started seeing this behavior in late April. I haven't found any official documentation announcing this change.
When some documentation appears, what I expect the new event venue workflow will be is something like:
Query the area where your event will take place to see if a venue exists already.
If yes, get save its id.
If not, create a new community page for your venue and save its id.
Use this ID to populate the event venue.
In the end this is a known facebook bug
https://developers.facebook.com/bugs/173095916131752
Two different formats when create using the same parameters.
When create event through gql
{
"id": "xxxxxxxxxxxxxx",
"owner": {
"name": "xxxxxxxxxx",
"id": "xxxxxxxxx"
},
"name": "W1112",
"start_time": "2013-10-22",
"is_date_only": true,
"location": "Tulsa, OK, United States",
"venue": {
"latitude": 36.131388888889,
"longitude": -95.937222222222,
"street": "",
"zip": "",
"id": "109436565740998"
},
"privacy": "SECRET",
"updated_time": "2013-09-19T12:23:26+0000"
}
When create event through fb
{
"id": "xxxxxxxxxxxxxx",
"owner": {
"name": "xxxxxx",
"id": "xxxxxxxx"
},
"name": "1234",
"start_time": "2013-10-09T21:26:00+1100",
"end_time": "2013-10-25T00:26:00+1100",
"timezone": "Australia/Sydney",
"is_date_only": false,
"location": "Maroubra Junction",
"venue": {
"latitude": -33.940804216453,
"longitude": 151.23876752992,
"city": "Maroubra",
"state": "NSW",
"country": "Australia",
"id": "153993547968514",
"street": "832 anzac Parade ",
"zip": "2035"
},
"privacy": "SECRET",
"updated_time": "2013-09-19T10:50:14+0000"
}