PayPal REST API - Coupon / Discount Code (Negative Numbers) - paypal

I've been unable to find an accurate answer for this.
As we know already, PayPal's REST API doesn't have a option for applying discount code. However, we can append another item to the item_list with a description of a I.e. Promo / Discount code.
So e.g. breaking this into human readable data, here's what I'm passing to the API.
Transaction
Amount: 100
item_list: [ product1, 60 ], [ product2, 60 ], [ coupon_code, -20 ]
Visually, This route should work (as it does in the classic API). However, the PayPal API doesn't allow negative numbers.
Ideally, we want to use the signed / OAuth route via PayPal REST API Vs. the open / classic API.
Update 1/13/2014
I noticed Storenvy has the ability to apply discounts to their connected user's PayPal accounts. However, If I recall Storenvy has a partnership with PayPal - I'm wondering if they're on a specific internal rest API version for the discount support?

I do it creating another item, and giving a negative price.
$item = new Item();
$price = -11.20;
......
$item->setName($name)
->setCurrency($currency)
->setQuantity($quantity)
->setSku($sku)
->setPrice($price);
For this example I have a Promo code of -11.20 euro:

What worked for me:
Add a discount field to the breakdown:
'discount' => [
'currency_code' => $order->currency,
'value' => $order->coupon_total,
]
See PayPal's docs: https://developer.paypal.com/docs/api/orders/v2/#definition-amount_breakdown
The discount will the show up as discount in the price breakdown.

Make negative value of coupon discount amount. It worked for me.
$itemArray = array();
if (isset($request->couponId)) {
// coupon object
$coupon = (new Promocodes())->check($request->couponId);
if (isset($coupon->code)) {
$item = new Item();
$item->setName('Coupon Discount')
->setCurrency('GBP')
->setQuantity(1)
->setPrice(($coupon->reward * (-1)));
// to reduce reward amount from total
$totalAmount -= $coupon->reward;
array_push($itemArray, $item);
}
}

For discount we do have the discount variables discount_amount and discount_percentage where you can get:
The amount and currency of the discount applied to the payment.
See the reference https://developer.paypal.com/docs/api/payments/ and search for the term "discount" there.
I hope this helps.

Related

ERPnext :custom script on sales invoice

I need to change amount calculation for each item in sales invoice to be:
amount = rate * qty * custom_field
I tried this, but it doesn't work.
frappe.ui.form.on("Sales Invoice Item", "custom_field", (frm, cdt, cdn) => {
var d = locals[cdt][cdn];
frappe.model.set_value("amount", d.qty*d.custom_field*d.rate) ;
});
Set value should be used like
frappe.model.set_value(DOC_TYPE, DOC_NAME, FIELD_NAME, NEW_VALUE);
So, in your case
frappe.model.set_value("Sales Invoice Item", cdn, "amount", d.qty*d.custom_field*d.rate);
Or
frappe.model.set_value(cdt, cdn, "amount", d.qty*d.custom_field*d.rate);

Display rowcount beside each filter at grid

I am using AG grid enterprise to display my data. I have filters for each columns. I want to show the count of each filter element inside the filter drop-down itself. Please help. It's like if the filter shows that we have only us and Canada in the country column, I want to display the frequencies of us and canada inside parenthesis beside these filter elements
Update: added working sample
filterParams: { cellRenderer: "countryFilterRenderer"}
countryFilterRenderer(params) {
let count = this.rowData.filter(i=>i.country.name==params.value).length;
return `${params.value}(${count})`;
}
rowData:[{country:{name:..., code:...}];
rowData definition just for clarity.
For more info check doc with samples, and official demo with sources.
Update: added hot data sample
Once we need to have data - related from sorting or filtering we can use API methods: forEachNodeAfterFilter, forEachNodeAfterFilterAndSort, getDisplayedRowCount.
sportFilterRenderer(params){
let count;
if(this.gridApi.getDisplayedRowCount() != this.rowData.length){
count = 0;
this.gridApi.forEachNodeAfterFilter(node=>{
if(node.data.sport == params.value)
count++;
})
}
else{
count = this.rowData.filter(i=>i.sport==params.value).length;
}
return `${params.value}(${count})`;
}
https://plnkr.co/edit/bCI0SJ (check country and sport filters)
On sample plnkr count in sport filter would be recalculated every time once you will select\deselect anything from country filter
Update: hot changes handling via cellRenderer
So ag-grid team noticed about this issues and they have it on backlock - before this - there is no way to handle your requirement in the same way as we tried. Here you can find an issue (AG-2078)

Get refund transaction details with PayPal NVP

Is it possible to retrieve refund details such as the parent transaction ID with the PayPal NVP API? So far I know it's possible to retrieve the details of a "Received" transaction by using "GetTransactionDetails" but for refunds it seems that method doesn't work.
body = {
USER: user_id,
PWD: password,
SIGNATURE: signature,
METHOD: 'GetTransactionDetails',
TRANSACTIONID: refund_id
VERSION: 204
}
response = HTTParty.post('https://api-3t.sandbox.paypal.com/nvp', body: body).
#Parsed response:
{
"ADDRESSOWNER"=>"PayPal", "ADDRESSSTATUS"=>"None",
"TIMESTAMP"=>"2018-03-15T11:04:45Z",
"CORRELATIONID"=>"97e8f9e1e9921", "ACK"=>"Failure",
"VERSION"=>"204", "BUILD"=>"39949200", "L_ERRORCODE0"=>"10004",
"L_SHORTMESSAGE0"=>"Invalid transaction type",
"L_LONGMESSAGE0"=>"You can not get the details for this type of transaction",
"L_SEVERITYCODE0"=>"Error",
"PENDINGREASON"=>"None",
"REASONCODE"=>"None",
"L_TAXABLE0"=>"false"
}
I've tested it again with another refund ID and I think my example from above failed as refunds for PayPal fees cannot be retrieved. Regular refunds can be retrieved with the GetTransactionDetails.

How to keep track of users making Stripe Payments

I'm currently trying to figure out a way for my MEAN stack application to keep track of which users have paid to grant them access to a certain portion of my webpage. I've considered several options: Stripe customer ID, MongoDB record, And HTML attribute I can update.
My mean stack keeps track of users by JWT, and it appears stripe assigns them their own customer ID which isn't ideal. Can it done with JWT as opposed to their forced cutomer ID?
MongoDB record. Which is what I'm thinking might be the best option. When a new user has been created, i'll give it an attribute of hasPaid = no. Then update the record of that customer when a payment is submitted. Then I guess run a script to set everyone back to unpaid each day?
HTML element/attribute. I don't know if this is even possible; but it would be cool to create a key that is carried during the HTML session after payment is received. If the person closers the browser then the session would be closed?
I'm looking for guidance on my 3 options to determine if they're the best solution. Also, if anyone has any suggestions as to alternatives, I'm all ears!
Thanks in advance.
Speaking generally, the most common approach would be the second one: use an attribute in your data model that indicates whether the user has paid/should be granted access. When a charge is created [0] successfully, update the model to indicate so, then filter access based on this attribute.
[0] https://stripe.com/docs/api/node#create_charge
Use a Boolean value in your user model.
var UserSchema = new Schema({
name: String,
hasPaid: {type: Boolean, default: false} //set this false
});
then in your REST API routes, the user buys the product; now set hasPaid to true
// req.user._id is passport config
User.findOneAndUpdate({_id: req.user._id}, {$set: {"hasPaid":istrue}}).exec(function(err) {
if(err) {
throw err;
}else {
req.flash('success', 'Thank you for submitting the form.');
res.render('charge', {
layout: 'dash',
user: req.user,
success: req.flash('success')
});
}
});
Now you can keep track of the users that purchased your products to grant them access to other parts of your site.
Stripe.js comes with Checkout.js which makes it even easier to use Stripe's service.
Copy and paste this into your html/jade/handlebars or view file. This will display a popup form to let the user type in his or her cc information.
<form action="/charge" method="POST">
<script
src="https://checkout.stripe.com/checkout.js"
class="stripe-button"
data-key="pk_test_bla3hf&kc033"
data-image="/square-image.png"
data-name="Demo Site"
data-description="2 widgets ($20.00)"
data-amount="2000">
</script>
</form>
You will receive a token once the user presses submit that you grab on your server. From inside your REST API route, you can charge the customer:
var token = req.body.stripeToken; // Using Express
// Create a charge: this will charge the user's card
var charge = stripe.charges.create({
amount: 1999, // Amount in cents
currency: "usd",
source: token,
metadata: {
user: req.user._id,
email: req.user.local.email
}
description: "Example charge" //keep track by writing a description or you can use the metadata property Stripe has to offer in the charges object
},function(err, charge) {
if (err && err.type === 'StripeCardError') {
// The card has been declined
}else {
res.redirect('/thanks-for-your-order');
console.log('charge here ' + charge.id); //store the id
console.log('charge here ' + charge.invoice); //store the invoice
console.log('charge here ' + charge.customer); //store the customer id
}
});
You can now track each order by storing the properties of the charge object in any model you wish.

Display Latest Magento products without setting date

I use Magento 1.7.0.2.
I'd like to show the 8 latest added products in my homepage, but without setting a date "from" and "to". I need it to be automatically.
Does anyone know of a solution?
Product IDs are incremental. By ordering them descending and limiting the collection to 8 you will have 8 last products.
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->getSelect()->order('entity_id desc')->limit(8);
/* just for testing
Mage::log($collection->getSelect()->assemble());
foreach ($collection as $product) {
Mage::log($product->getSku());
} */
With the collection you can do whatever you need, add visibility and status filter etc.
in order to do that you will need to use the date that the order was created. The key to display all products information as price, name, and etc. is to us ->addAttributeToSelect('*') Here is the script:
$store_id = Mage::app()->getStore()->getId();
$_products = Mage::getResourceModel('reports/product_collection')
->addStoreFilter($store_id)
->addAttributeToFilter('visibility', 4)
->addAttributeToFilter('status', 1)
->addAttributeToSelect('*')
->setVisibility(array(2,3,4))
->setOrder('created_at', 'desc')
->setPage(1, 9);