Can someone help me with paypal chained payments? PHP - php

I am new to doing anything with paypal, and it's frustrating to me. I am just trying to create the chained payment with this here using sandbox business account:
$api = "https://svcs.sandbox.paypal.com/AdaptivePayments/Pay";
$input = array(
"actionType" => "CREATE",
"currencyCode" => "USD",
"feesPayer" => "EACHRECEIVER",
"memo" => "TestNote",
"receiverList" => array(
"receiver" => array( //first goes to merchant(95% of payment)
"amount" => "95.00",
"email" => "rbxseller#gmail.com",
"primary" => true
),
"receiver" => array( //then sends 5% commission to owner of site
"amount" => "5.00",
"email" => "rbxowner#gmail.com",
"primary" => false
)
),
"requestEnvelope" => array(
"errorLanguage" => "en_US"
)
);
$headers = array(
"X-PAYPAL-SECURITY-USERID: ".USER_ID,
"X-PAYPAL-SECURITY-PASSWORD: ".USER_PASS,
"X-PAYPAL-SECURITY-SIGNATURE: ".USER_SIG,
"X-PAYPAL-REQUEST-DATA-FORMAT: NV",
"X-PAYPAL-RESPONSE-DATA-FORMAT: JSON",
"X-PAYPAL-APPLICATION-ID: APP-80W284485P519543T"
);
$ch = curl_init($api);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($input));
$response = curl_exec($ch);
var_dump($response);
I got the error response:
[{"errorId":"580001","domain":"PLATFORM","subdomain":"Application","severity":"Error","category":"Application","message":"Invalid request: {0}"}]
Thank you for taking time to reply!

You're not going to be able to simply submit an array of data to the PayPal end point. You'll need to build out an XML request for Adaptive Payments.
I would recommend you take a look at my PayPal PHP Class Library, which works in very much the same way you're trying to work here, except that it would take your array data, generate the XML request, send it to PayPal, parse the XML result and return an array back to you.
It supports all PayPal APIs including Adaptive Payments, and it comes with fully functional samples as well as ready-made template files to start fresh calls with.

Related

PayPal Chained Payment Help [PHP]

I'm just trying to do a test with paypal chained payments, and it's really frustrating. My goal for this test is to send the primary receiver $15 and then $1 to a secondary receiver. Here is my code:
$api = "https://svcs.sandbox.paypal.com/AdaptivePayments/Pay";
$input = array(
"actionType" => "PAY",
"currencyCode" => "USD",
"feesPayer" => "EACHRECEIVER",
"cancelUrl" => "https://www.google.com", //test url
"returnUrl" => "https://www.google.com", //test url
"receiverList" => array(
"receiver" => array( //send primary receiver $15
"amount" => "15.00",
"email" => "rbxseller1#gmail.com",
"primary" => true
),
"receiver" => array( //send owner of site $1 commission
"amount" => "1.00",
"email" => "rbxowner#gmail.com",
"primary" => false
)
),
"requestEnvelope" => array(
"errorLanguage" => "en_US"
)
);
$headers = array(
"X-PAYPAL-SECURITY-USERID: ".USER_ID, //predefined
"X-PAYPAL-SECURITY-PASSWORD: ".USER_PASS, //predefined
"X-PAYPAL-SECURITY-SIGNATURE: ".USER_SIG, //predefined
"X-PAYPAL-REQUEST-DATA-FORMAT: JSON",
"X-PAYPAL-RESPONSE-DATA-FORMAT: JSON",
"X-PAYPAL-APPLICATION-ID: APP-80W284485P519543T"
);
$ch = curl_init($api);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($input));
$response = curl_exec($ch);
var_dump($response);
When I try to do this, it works, but in my payment details it only shows the $1 to the secondary receiver, there is no trace of the primary receiver:
{"paymentInfo":[{"receiver":{"amount":"1.00","email":"rbxowner#gmail.com","primary":"false","paymentType":"SERVICE","accountId":"6LBSVJQNVE9DA"},"pendingRefund":"false"}]}
I tried setting the "actionType" to "PAY_PRIMARY" and it gave me this error:
"message":"Invalid request parameter: action type PAY_PRIMARY can only be used in chained payments","parameter":["PAY_PRIMARY"]
It's getting quite frustrating as I've looked it up on youtube, stackoverflow, some forum websites, etc and haven't found much helpful info.
Thank you very much to anyone who will take the time to read this and help me!
Your mistake is in the PHP array syntax here:
"receiverList" => array(
"receiver" => array(/*primary receiver info*/),
"receiver" => array(/*secondary receiver info*/)
),
An associative array can only have one value for each key (to picture why, imagine accessing $receiverList['receiver'] from an array declared this way; it wouldn't know which you wanted).
To PHP, this is the same as writing $foo = 1; $foo = 2; and expecting both 1 and 2 to still be "there" somewhere. So all that gets sent to Paypal is this:
"receiverList" => array(
"receiver" => array(/*secondary receiver info*/)
),
You can see this for yourself if you echo out json_encode($input).
I don't know what the array should look like, but it's definitely not that. My best guess without seeing the documentation would be a simple list with no keys specified:
"receiverList" => array(
array(/*primary receiver info*/),
array(/*secondary receiver info*/)
),
Or possibly the "recevier" key needs to be there, and the two entries are inside that:
"receiverList" => array(
"receiver" => array(
array(/*primary receiver info*/),
array(/*secondary receiver info*/)
)
),
Or perhaps you've misread the docs and there is no "receiverList" key, only "receiver":
"receiver" => array(
array(/*primary receiver info*/),
array(/*secondary receiver info*/)
),
Whichever variant it is, there's no point changing the rest of your query until you get this bit right, because right now you are only sending one set of receiver details to Paypal.

implicit paypal payment - PAY - You do not have permission to execute this payment implicitly

I want to perform an implicit payment from my account (the paypal api signed one) into another (or multiple as parallel payment).
I decided to use Adaptive Payments and have implemented the function to call the Pay action as follows
$bodyparams = array (
"requestEnvelope.errorLanguage" => "en_US",
'actionType' => 'PAY',
'currencyCode' => 'USD',
'receiverList.receiver(0).email' => 'receiver#domain.com',
'receiverList.receiver(0).amount' => '1.00',
'senderEmail' => 'myaccount#domain.com',
'memo' => 'Test memo',
'ipnNotificationUrl' => 'http://google.com',
'cancelUrl' => 'http://google.com',
'returnUrl' => 'http://google.com'
);
$url = "https://svcs.paypal.com/AdaptivePayments/Pay";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'X-PAYPAL-SECURITY-USERID: XXX',
'X-PAYPAL-SECURITY-PASSWORD: XXX',
'X-PAYPAL-SECURITY-SIGNATURE: XXX',
'X-PAYPAL-REQUEST-DATA-FORMAT: NV',
'X-PAYPAL-RESPONSE-DATA-FORMAT: JSON',
'X-PAYPAL-APPLICATION-ID: APP-XXX',
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($bodyparams));
$response = json_decode(curl_exec($ch));
$pk="";
if(isset($response->responseEnvelope) && $response->responseEnvelope->ack == "Success"){
$pk = $response->payKey;
}else{
die(var_dump($response));
}
$ch = curl_init();
header("Location: https://www.paypal.com/cgi-bin/webscr?cmd=_ap-payment&paykey=".$pk);
die();
Paypal returns me "You do not have permission to execute this payment implicitly"
{
"responseEnvelope": {
"timestamp": "2016-05-19T10:05:05.407-07:00",
"ack": "Failure",
"correlationId": "22e0930fcae7d",
"build": "20420247"
},
"error": [
{
"errorId": "550001",
"domain": "PLATFORM",
"subdomain": "Application",
"severity": "Error",
"category": "Application",
"message": "You do not have permission to execute this payment implicitly"
}
]
}
But when I switch the 2 accounts (i.e. just for test, the other account sends me the money), I get redirected to the approval process.
Now, the app I am using has the flag as shown in the picture below
What should I check? It seems that paypal doesn't allow me to send implicit payments, but don't know for what reason (paypal support were not be able to say anything else then give me some links).
IMPORTANT EDIT
If I use the sandbox credentials, the payment is "COMPLETED"

Neteller TransferOut with PHP / CURL

I'm having some problems using the Neteller API to transfer money out of our merchant account to a user. I've succcessfully received the accessToken, however when I try using transferOut I just get invalid credentials? The code I'm using is:
$headers = array(
"Content-type" => "application/json",
"Authorization" => "Bearer " . $accessToken
);
//build the request body structure
$requestParams = array(
"payeeProfile" => array(
"email" => $the_email_address_to_send_to
),
"transaction" => array(
"merchantRefId" => $transaction_id,
"amount" => $amount,
"currency" => $currencyCode
)
);
// encode the requestParams to a string
$requestParams = json_encode($requestParams);
// The curl stuff
$curl = curl_init();
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_URL, "https://api.neteller.com/v1/transferOut");
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $requestParams);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
// Ok lets send this lovely looking curl over
$serverOutput = json_decode(curl_exec($curl));
Obviously all variables ($transaction_id, $amount, $currency) are set appropriately. However the response I get back is:
stdClass Object
(
[error] => stdClass Object
(
[code] => 5279
[message] => Authentication credentials are invalid
)
)
I'm confused, surely the accessToken is the credentials I need, and theyve already been received. Am I meant to include anything else in the transferOut curl postfields?
Thanks in advance
As per user3584460's comment:
$headers does not look OK - try $headers = array("Content-type: application/json", "Authorization: Bearer " . $accessToken);. At least this is the format according to http://php.net/manual/en/function.curl-setopt.php
Note, the Merchant Ref ID also needs to be a certain length. unsure what - can't find reference, but 8 characters is not long enough.

Getting invalid token id using stripe connect

I am using Stripe Connect for stripe integration. In this, we firstly create a managed account under an existing stripe account. Then we charge the customer and the charge is transferred to one account and application fee to the managed account. By creating a managed account, we get the account id associated to it using:
$acc=\Stripe\Account::create(
array(
"country" => "US",
"managed" => true
)
);
Then we charge customer and link two accounts with that charge using application fee concept as follows:
$c_charge = \Stripe\Charge::create(
array(
"amount" => 1000, // amount in cents
"currency" => "usd",
"source" => {TOKEN OF CUSTOMER},
"description" => "Example charge",
"application_fee" => 123 // amount in cents
),
array("stripe_account" => 'acct_15rTMLISz4VN6mw2')
);
In this case since the stripe account with which the application fee is linked has no bank account connected for money transfer, so now we need to link the bank account with the stripe account
Following code is based on it, but it generates an error: Invalid token id
$data=array(
'bank_account'=> $token
);
$pHttp_headers=array(
"Content-Type: application/x-www-form-urlencoded",
"Authorization: Bearer {$stripe['secret_key']}"
);
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,"https://api.stripe.com/v1/accounts/acct_15rTMLISz4VN6mw2/bank_accounts");
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $pHttp_headers);
//curl_setopt($ch, CURLOPT_USERPWD,$stripe['secret_key']);
$pResult = curl_exec($ch);
curl_close($ch);
$pResult=json_decode($pResult,true);
This is the error I am getting:
Array ( [error] => Array ( [type] => invalid_request_error [message] => Invalid token id: tok_15rlFFHPiBMaAbxH6hwPNcDL [param] => bank_account ) )
Any ideas?

Paypal Adaptive Payments (Chained) - Unilateral receiver not allowed in chained payment

I have been trying to implement split payments using the Paypal Adaptive Payments API. I have got a simple parallel payment to work, however this shows both split payments to the buyer.
Basically I am selling a membership. Our local association should get 75% of the funds and 25% is passed on to the governing body. The member should only see the total amount as being a 2015 membership so I started to look into chained payments instead. This on the face of it looks like a very simple code change but is causing me issues in relation to unilateral payments.
I am implementing this in php.
So here is the paypal send method
function PaypalSend($payment_details, $api_function){
// initial endpoint that starts the transaction
$paypalInitialEndpoint = 'https://svcs.sandbox.paypal.com/AdaptivePayments/';
// set http headers
$headers = array(
'Connection: Close',
'X-PAYPAL-SECURITY-USERID: testseller_api1.nipf.com',
'X-PAYPAL-SECURITY-PASSWORD: 1381912839',
'X-PAYPAL-SECURITY-SIGNATURE: AzykGe5AzfK.mJFMRzBwIcTap-LcAsmsP4AhYzk1Y-07mh-xPLc-goK3',
'X-PAYPAL-APPLICATION-ID: APP-80W284485P519543T',
'X-PAYPAL-REQUEST-DATA-FORMAT: JSON',
'X-PAYPAL-RESPONSE-DATA-FORMAT: JSON'
);
// setup curl request and http headers
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $paypalInitialEndpoint . $api_function);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payment_details));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if(!($res = curl_exec($ch)) )
{
error_log(curl_error($ch));
curl_close($ch);
exit;
}
curl_close($ch);
return json_decode($res, TRUE);
}
And here is my chained payment method. This code needs a lot of refactoring but was fully functional with the parallel payments with only minor changes to this current code.
function sendChainedPayment(){
$purchase_details_array = array(
"actionType" => "PAY",
"currencyCode" => "GBP",
"feesPayer" => "PRIMARYRECEIVER",
"memo" => "blah blah blah",
"receiverList" => array(
"receiver" => array(
array(
"amount" => "30.00",
"email" => "testseller#nipf.com",
"primary" => "true"
),
array(
"amount" => "10.00",
"email" => "testseller#gbpf.com",
"primary" => "false"
)
)
),
"returnUrl" => "http://localhost/membershipSuccess.php",
"cancelUrl" => "http://localhost/membershipCancel.php",
"requestEnvelope" => array(
"errorLanguage" => "en_UK",
"detailLevel" => "ReturnAll"
)
);
$response = PaypalSend($purchase_details_array, "Pay");
//echo json_encode($response) . "<br /><br />";
$payKey = $response['payKey'];
$payment_details = array(
"requestEnvelope" => array(
"errorLanguage" => "en_UK",
"detailLevel" => "ReturnAll"
),
"payKey" => $payKey,
"receiverOptions" => array(
array(
"receiver" => array("email" => "testseller#nipf.com"),
"invoiceData" => array(
"item" => array(
array(
"name" => "Membership 2015",
"price" => "30.00",
"identifier" => "Membership 2015: joe bloggs"
)
)
)
),
array(
"receiver" => array("email" => "testseller#gbpf.com"),
"invoiceData" => array(
"item" => array(
array(
"name" => "Membership 2015 (Fee)",
"price" => "10.00",
"identifier" => "Membership 2015 (Fee): joe bloggs"
)
)
)
)
)
);
$response = PaypalSend($payment_details, "SetPaymentOptions");
//echo json_encode($response) . "<br /><br />";
$paypalCustomerUrl = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_ap-payment&paykey=' . $payKey;
echo $paypalCustomerUrl;
//header('Location: ' . $paypalCustomerUrl);
}
I am getting the following response JSON with the first callout. I think this is to do with the accounts being just sandbox accounts rather than real accounts but how am I meant to test this in the sandbox if the accounts all have to be real accounts? In this case the account used as the API account is the primary receiver.
{"responseEnvelope":{"timestamp":"2015-02-04T14:37:26.598-08:00","ack":"Failure","correlationId":"749bd1d709e76","build":"15089777"},"error":[{"errorId":"520009","domain":"PLATFORM","subdomain":"Application","severity":"Error","category":"Application","message":"Account Account not found. Unilateral receiver not allowed in chained payment is restricted","parameter":["Account not found. Unilateral receiver not allowed in chained payment"]}]}
I was getting the same error message, and I fixed it by making sure that the 2 email addresses that I was sending payments to in the API call were both sandbox accounts. They didn't exist as real email addresses, but they did need to exist as paypal accounts. (Previously I was sending them to 2 actual live paypal accounts that didn't exist in the sandbox).
Judging by the error message, "Account not found. Unilateral receiver not allowed in chained payment", it just can't find your account, probably because they are not sandbox accounts.

Categories