PayPal Smart Payment Buttons - Alternative Payment Methods - 400 Bad Request - paypal

I'm using the PayPal Smart Payment Buttons on my website to capture payments.
The Order is created server-side via the PayPal-checkout-sdk for PHP.
$request = new OrdersCreateRequest();
$request->prefer('return=representation');
$request->body = self::buildRequestBody($paymentAC);
// 3. Call PayPal to set up a transaction
$client = PayPalClient::client();
$response = $client->execute($request);
The request body looks like this:
return array(
'intent' => 'CAPTURE',
'commit' => true,
'application_context' =>
array(
'brand_name' => 'EXAMPLE INC',
'locale' => 'de-DE'
'shipping_preference' => 'NO_SHIPPING'
),
'purchase_units' =>
array(
0 =>
array(
'reference_id' => $rId,
'description' => 'Ihr kauf bei EXAMPLE INC',
'invoice_id' => $paymentAC,
'amount' =>
array(
'currency_code' => $currency, #EUR
'value' => $price,
'breakdown' =>
array(
'item_total' =>
array(
'currency_code' => $currency,
'value' => $itemTotal,
),
'tax_total' =>
array(
'currency_code' => $currency,
'value' => 0,
),
),
),
'items' => $items,
),
),
);
The request works fine and an order is created. The script returns a JSON Object with the "id" key set to the ID of the created order.
{"id": "PAYMENTID"}
The script is called by the payment button like this:
paypal.Buttons({
createOrder: function() {
return fetch('./CreateOrder.php', {
method: 'post',
headers: {
'content-type': 'application/json'
},
body: '{"payment_ac": "<?php echo $_GET['code'] ?>"}'
}).then(function(res) {
console.log(res);
return res.json();
}).then(function(data) {
return data.id; // Use the key sent by your server's response, ex. 'id' or 'token'
});
},
onError: (err) => {
console.error('error from the onError callback', err);
},
onApprove: function(data, actions) {
// This function captures the funds from the transaction.
$("#loadMe").modal({
backdrop: "static", //remove ability to close modal with click
keyboard: false, //remove option to close with keyboard
show: true //Display loader!
});
return actions.order.capture().then(function(details) {
// This function shows a transaction success message to your buyer.
console.log(details);
//window.location.href = "verify.php?id=" + data.orderID + "&ac=<?php echo $internalID ?>";
$.get({
url: "/payment/verify.php?id=" + data.orderID + "&ac=<?php echo $internalID ?>",
success: function (respdata) {
if (respdata['payment'] === "completed") {
window.location.href = '/success/<?php echo $internalID?>&cid=' + respdata['cid'];
} else {
alert(respdata);
}
}
})
});
},
onCancel: function (data) {
console.log(data);
alert(data);
// Show a cancel page, or return to cart
window.location.href = "/payment/cancelled.php?ac=<?php echo $internalID ?>&oid=" + data.orderID;
},
style: {
color: 'black',
label: 'pay',
layout: 'vertical'
}
}).render('#paypal-button-container');
The payment buttons can open the checkout window successfully.
When I'm using sandbox credentials everything works fine. (PayPal, Simulated Alternative Payments & Credit Card payments)
When I'm switching to live credentials only PayPal payments seem to work. Every alternative payment method redirects to https://www.paypal.com/latinumcheckout/error/generic-error after you enter your details on https://www.paypal.com/latinumcheckout/change-userinfo
When in the developer console there is an error output:
the server responded with a status of 400 () app.bundle.js:41:140543
Credit card payments seem to fail as well.
I'm clueless, I spent a long time reading the documentation but have found no solution.

Related

Ionic 2 - FCM custom sound notification

I have implemented FCM notification using PHP to send notification on mobile.
Notification working properly but I want to add sound to the notification.
I followed Ionic documentation for FCM.
this.fcm.getToken().then(token =>{
alert("token : "+token);
});
this.fcm.onNotification().subscribe(data => {
alert("data :"+ JSON.stringify(data));
if(data.wasTapped){
alert("Received in background : "+ JSON.stringify(data.msg));
} else {
alert("Received in foreground : "+ JSON.stringify(data.msg));
}
}, err =>{
alert("Received err : "+ err);
})
My php payload:
$message['msg'] = 'notification text';
$message['sound'] = 1;
$message['vibrate'] = 1;
$fields = array(
'registration_ids' => $tokenIds,
'data' => array('message' => $message)
);
i'm sending $fields to notification plugin
Did anyone implement this kind of functionality?
In your push notification payload set following properties.
You need to set sound property to default
"notification":{
"title":"Notification title",
"body":"Notification body",
"sound":"default",
"click_action":"FCM_PLUGIN_ACTIVITY",
"icon":"fcm_push_icon"
},
At php server side i have set $fields array like this
$fields = array(
'registration_ids' => $tokenIds,
'data' => array('message' => $message,
'click_action' => "FCM_PLUGIN_ACTIVITY",
'sound'=>'default'),
'notification'=>array('message' => $message,
'click_action' => "FCM_PLUGIN_ACTIVITY",
'sound'=>'default'),
'priority'=> "high"
);
this can work for fcm notification at background and for sound in ionic

PayPal Receipt not showing Description information using SetExpressCheckout

I am using PayPal's API to process a payment using SetExpressCheckout method.
$requestParams = array(
'RETURNURL' => 'SUCCESS_PAGE_URL',
'CANCELURL' => 'CANCE_PAGE_URL'
);
$orderParams = array(
'PAYMENTREQUEST_0_AMT' => $price,
'PAYMENTREQUEST_0_SHIPPINGAMT' => '0',
'PAYMENTREQUEST_0_CURRENCYCODE' => 'USD',
'PAYMENTREQUEST_0_ITEMAMT' => $price
);
$item = array(
'L_PAYMENTREQUEST_0_NAME0' => $item_name,
'L_PAYMENTREQUEST_0_DESC0' => $item_description,
'L_PAYMENTREQUEST_0_AMT0' => $price,
'L_PAYMENTREQUEST_0_QTY0' => '1'
);
$paypal = new Paypal();
$response = $paypal -> request('SetExpressCheckout',$requestParams + $orderParams + $item);
It all works great, but even though the description is showing in the PayPal's checkout page, the email receipt that I get is missing the description information.
Does anyone know what how I can get the description to show on the receipt?
Figured it out. When the SetExpressCheckout is done and returns "Success" it gets redirected to PayPal, after which it goes back to your specified RETURNURL. On this RETURNURL page, for DoExpressCheckoutPayment, you need to specify the order details, this is what shows up in the invoice. Here is the code:
// Complete the checkout transaction
$requestParams = array(
'TOKEN' => $_GET['token'],
'PAYMENTACTION' => 'Sale',
'PAYERID' => $_GET['PayerID'],
'PAYMENTREQUEST_0_AMT' => '1', // Same amount as in the original request
'PAYMENTREQUEST_0_CURRENCYCODE' => 'USD' // Same currency as the original request
);
$item = array(
'L_PAYMENTREQUEST_0_NAME0' => $name,
'L_PAYMENTREQUEST_0_DESC0' => $desc, // <-- this is the description
'L_PAYMENTREQUEST_0_AMT0' => $price,
'L_PAYMENTREQUEST_0_QTY0' => '1'
);
$response = $paypal -> request('DoExpressCheckoutPayment',$requestParams + $item);

Get customer Email in return URL after making payment using PayPal button

How can i get customer Email in return URL after making payment using PayPal button?
Thanks.
<?php
if(isset($_GET['tx']))
{
$tx = $_GET['tx'];
$your_pdt_identity_token = //token
$request = curl_init();
// Set request options
curl_setopt_array($request, array
(
CURLOPT_URL => 'https://www.sandbox.paypal.com/cgi-bin/webscr', //sandbox!!!
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => http_build_query(array
(
'cmd' => '_notify-synch',
'tx' => $tx,
'at' => $your_pdt_identity_token,
)),
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HEADER => FALSE,
// CURLOPT_SSL_VERIFYPEER => TRUE,
// CURLOPT_CAINFO => 'cacert.pem',
));
// Execute request and get response and status code
$response = curl_exec($request);
$status = curl_getinfo($request, CURLINFO_HTTP_CODE);
// Close connection
curl_close($request);
}
if($status == 200 AND strpos($response, 'SUCCESS') === 0)
{
$singlequantity = explode("\n",$response);
$email = $singlequantity[15];
$count = null;
$email = preg_replace('"%40"', '#', $email, -1, $count);
preg_match("/payer_email=(.*)/", $email, $email);
}
else
{
echo '<script type="text/javascript">
window.location="cancel.php";
</script>';
}
?>
i know i shoved it in real hard right now , but this might be useful to other users attempting to do this.

PayPal Adaptive Payment SetPaymentOptions - does it work?

I've been trying (fruitlessly!) to get PayPals SetPaymentOptions API feature to work, as per: https://developer.paypal.com/docs/classic/api/adaptive-payments/SetPaymentOptions_API_Operation/
FWIW - I'm aware the below isn't truly JSON, but its the Perl object I'm creating - which gets converted into JSON before sending (its just easier to read like this, compared to having it all on one line =))
So far I create the initial payment using the "Pay" feature (https://svcs.sandbox.paypal.com/AdaptivePayments/Pay):
{
requestEnvelope => {
detailLevel => "ReturnAll",
errorLanguage => "en_US",
},
actionType => "PAY",
currencyCode => "USD",
receiverList => {
receiver => [
{
amount => 65,
email => 'user1#gmail.com',
paymentType => "GOODS",
invoiceId => "test"
},
{
amount => 15,
email => 'user2#gmail.com',
paymentType => "GOODS",
invoiceId => "test 2"
}
],
},
returnUrl => 'http://xx.com/thanks.html',
cancelUrl => 'http://xx.com/cancel.html',
}
This creates it fine, and I get returned back the payKey just fine. The problem starts when I try and add shipping/units prices/taxes etc via SetPaymentOptions. Here is an example request I'm making:
{
payKey => $json_returned->{payKey},
requestEnvelope => {
detailLevel => "ReturnAll",
errorLanguage => "en_US",
},
receiverOptions => [
{
customId => "foo123",
receiver => {
email => 'andy-facilitator#ultranerds.com'
},
invoiceData => {
item => [{
name => "ITEM1",
price => 50,
itemCount => 2,
itemPrice => 25,
}],
totalTax => 5,
totalShipping => 10,
},
SenderOptions => {
addressOverride => 1,
requireShippingAddressSelection => 1
}
}
]
}
I then grab back that transaction to see if it all got saved ok, by using a PaymentDetails request (https://svcs.sandbox.paypal.com/AdaptivePayments/PaymentDetails)
This always comes back with no shipping, tax, unit numbers, etc. I'm at a real loss as to whats going on - because if I were to change (for example) the number of units in this 2nd request, or the delivery price... it gives me an error that the numbers don't match up! So it has to be recognizing it - but just not doing anything with it
I'm really at my witts end here (I wish they'd hurry up and get the REST APIs finished up - as they look more promising than this... but for now, I've got to make do with what we have here with the Adaptive Payments)
UPDATE:
Is this what you mean with regards to running the ExecutePayment?
my $pass_in_params = {
payKey => $json_returned->{payKey},
requestEnvelope => {
detailLevel => "ReturnAll",
errorLanguage => "en_US",
},
actionType => "CREATE"
};
WAHOO - Finally got it working! As per Andrews info, the reason I wasn't seeing the shipping/units/tax stuff with the ExecutePayment request, is because we hadn't sent them to the payment page yet (and you can't grab it until the payment is complete). With the Sandbox, you can login to a test account and see all the units etc perfectly.
When you use Pay with CREATE and then call SetPaymentOptions behind that, no payment occurs until you finish it up with ExecutePayment. As such, when you call PaymentDetails there are no details to obtain.
Try calling ExecutePayment to finish things off and then see if PaymentDetails works better for you.

Yii CJuiAutoComplete default display value and clearing it on click

I have below CJuiAutoComplete and when loading I want to display "Search" in the text field and on click I want to clear . I tried using "value" under options , but couldn't make it work . Thanks for your help
tried also
'htmlOptions'=>array('value'=>'Search',)
<?php
$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
'name'=>'test1',
'source'=>'js: function(request, response) {
$.ajax({
url: "'.$this->createUrl('myAutoComplete/autoCompleate').'",
dataType: "json",
data: {
term: request.term,
brand: $("#type").val()
},
success: function (data) {
response(data);
}
})
}',
'options' => array(
'showAnim' => 'fold',
'select' => 'js:function(event, ui){ alert(ui.item.value) }',
'click'=>'js:function( event, ui ) {
alert("test");
return false;
}',
),
'htmlOptions'=>array('value'=>'Search',)
));
?>
Regards
UPDATE
directly putting 'value' =>'Search' worked .
Checking for click handler
Kiran
What you can do is give your widget an id and then you place the onClick event in the widget's htmlOptions and using JavaScript you clear the value.
$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
'id' => 'test1_id',
'name'=> 'test1',
'source'=>'js: function(request, response) {
$.ajax({
url: "'.$this->createUrl('myAutoComplete/autoCompleate').'",
dataType: "json",
data: {
term: request.term,
brand: $("#type").val()
},
success: function (data) {
response(data);
}
})
}',
'options' => array(
'showAnim' => 'fold',
'select' => 'js:function(event, ui){ alert(ui.item.value) }',
),
'htmlOptions' => array(
'onClick' => 'document.getElementById("test1_id").value=""'
)
));
You cannot put onClick in the options attribute as these are jQuery options for the CJuiAutocomplete, onClick is not defined in the JUI Autocomplete options.
Cheers
Old thread, but for newbies who land up here, its simple to add a html placeholder attribute in Yii CAutoComplete. See code below and add in the htmloptions line:
<?php $this->widget('CAutoComplete', array(
'model'=>$model,
'attribute'=>'tags',
'url'=>array('suggestTags'),
'multiple'=>true,
'htmlOptions'=>array('size'=>50,'placeholder'=>'Seperate tags with commas'),
)); ?>