How do I specify VAT in an order? - stripe-payments

We're based in the EU. When we sell our digital products to private persons or companies without a VAT number, we have to charge them VAT (Value Added Tax). This is what I'm trying:
import stripe
stripe.api_key = 'sk_test_xxx'
stripe.api_version = '2015-10-16'
product = stripe.Product.create(
id='product',
name='Product',
shippable=False
)
sku = stripe.SKU.create(
product='product',
price=100,
currency='eur',
inventory={'type': 'infinite'}
)
customer = stripe.Customer.create(
email='customer#example.org',
description="Customer"
)
order = stripe.Order.create(
customer=customer.id,
currency='eur',
items=[
{
'type': 'sku',
'quantity': 5,
'parent': sku.id,
'amount': 500
},
{
'type': 'tax',
'description': "20% VAT",
'amount': 100
}
]
)
The Order creation call gives me:
stripe.error.InvalidRequestError: Request req_xxx: Items of type tax are not supported at order creation.
When I replace the last order creation call without the tax:
order = stripe.Order.create(
customer=customer.id,
currency='eur',
items=[
{
'type': 'sku',
'quantity': 5,
'parent': sku.id,
'amount': 500
}
]
)
I'm getting back these order['items']:
[
{
"amount": 500,
"currency": "eur",
"description": "Product",
"object": "order_item",
"parent": "sku_xxx",
"quantity": 5,
"type": "sku"
},
{
"amount": 0,
"currency": "eur",
"description": "Taxes (included)",
"object": "order_item",
"parent": null,
"quantity": null,
"type": "tax"
},
{
"amount": 0,
"currency": "eur",
"description": "Free shipping",
"object": "order_item",
"parent": "ship_free-shipping",
"quantity": null,
"type": "shipping"
}
]
However, an order does not allow updating the items field after the order has been created.
What's the correct and semantic way to add VAT to the order items?

I contacted Stripe support and this should now be possible in a private beta. You can ask Stripe to join the taxes beta.
After joining, you can access documentation here: https://stripe.com/docs/relay#shipping-and-taxes and here: https://stripe.com/docs/relay/dynamic-shipping-taxes#order-creation-event.
There will be an option in your Stripe dashboard (Relay settings) to specify a "dynamic" taxes webhook where Stripe sends an Order to, and your server should then respond with a Order Item containing a tax entry. The webhook is hit immediately after creating an Order.

Related

Stripe: Get all the transactions involved in a payout paid event webhook

I am subscribing to the payout.paid event of stripe.
The payout object has the following object:
{
"id": "po_1H50scIkcSPJwVI7bFSQmBnV",
"object": "payout",
"amount": 1100,
"arrival_date": 1594782118,
"automatic": true,
"balance_transaction": "txn_1H2z37IkcSPJwVI7rVwkvfCT",
"created": 1594782118,
"currency": "usd",
"description": "STRIPE PAYOUT",
"destination": "ba_1H50scIkcSPJwVI7MshqFr6u",
"failure_balance_transaction": null,
"failure_code": null,
"failure_message": null,
"livemode": false,
"metadata": {},
"method": "standard",
"source_type": "card",
"statement_descriptor": null,
"status": "in_transit",
"type": "bank_account"
}
Ref: https://stripe.com/docs/api/payouts/object
I am able to get this event in my webhook but I am interested in getting the transactions "involved" in this Payout.
Let's say if the payout is of $100 and I have two products of $2 and $5 each, I need to determine how many of those transactions are there from each price.
Not able to find it in docs but from the UI we can do this by going to the individual payout from the payouts screen from the "export" button beside the transactions section header:
You'd use the "List all Balance Transactions" endpoint and specify the Payout ID there: https://stripe.com/docs/api/balance_transactions/list#balance_transaction_list-payout
That way you receive a list of all balance transactions that were a part of that specific Payout.

How to find common struct for all documents in collection?

I have an array of documents, that have more or less same structure. But I need find fields that present in all documents. Somethink like:
{
"name": "Jow",
"salary": 7000,
"age": 25,
"city": "Mumbai"
},
{
"name": "Mike",
"backname": "Brown",
"sex": "male",
"city": "Minks",
"age": 30
},
{
"name": "Piter",
"hobby": "footbol",
"age": 25,
"location": "USA"
},
{
"name": "Maria",
"age": 22,
"city": "Paris"
},
All docs have name and age. How to find them with ArangoDB?
You could do the following:
Retrieve the attribute names of each document
Get the intersection of those attributes
i.e.
LET attrs = (FOR item IN test RETURN ATTRIBUTES(item, true))
RETURN APPLY("INTERSECTION", attrs)
APPLY is necessary so each list of attributes in attrs can be passed as a separate parameter to INTERSECTION.
Documentation:
ATTRIBUTES: https://www.arangodb.com/docs/stable/aql/functions-document.html#attributes
INTERSECTION: https://www.arangodb.com/docs/stable/aql/functions-array.html#intersection
APPLY: https://www.arangodb.com/docs/stable/aql/functions-miscellaneous.html#apply

How to make a payment on quickbooks using QB online

I am able to create invoice on the quickbooks. But I need to set the payment as paid and set the payment option as credit card for a particular invoice. Here is the payment object.
{
"TotalAmt": 25.0,
"CustomerRef": {
"value": "20"
}
}
But there is no option to set the invoice Id here or the card option. Here is the reference
Example copy/pasted from the reference you linked to in your post:
{
"TxnDate": "2015-01-16",
"TotalAmt": 65.0,
"Line": [
{
"Amount": 55.0,
"LinkedTxn": [
{
"TxnId": "70",
"TxnType": "Invoice"
}
]
}
],
"CustomerRef": {
"name": "Red Rock Diner",
"value": "20"
}
}

Update inner object in arangodb

I have an object stored in arangodb which has additional inner objects, my current use case requires that I update just one of the elements.
Store Object
{
"status": "Active",
"physicalCode": "99999",
"postalCode": "999999",
"tradingCurrency": "USD",
"taxRate": "14",
"priceVatInclusive": "No",
"type": "eCommerce",
"name": "John and Sons inc",
"description": "John and Sons inc",
"createdDate": "2015-05-25T11:04:14+0200",
"modifiedDate": "2015-05-25T11:04:14+0200",
"physicalAddress": "Corner moon and space 9 station",
"postalAddress": "PO Box 44757553",
"physicalCountry": "Mars Sector 9",
"postalCountry": "Mars Sector 9",
"createdBy": "john.doe",
"modifiedBy": "john.doe",
"users": [
{
"id": "577458630580",
"username": "john.doe"
}
],
"products": [
{
"sellingPrice": "95.00",
"inStock": "10",
"name": "School Shirt Green",
"code": "SKITO2939999995",
"warehouseId": "723468998682"
},
{
"sellingPrice": "95.00",
"inStock": "5",
"name": "School Shirt Red",
"code": "SKITO245454949495",
"warehouseId": "723468998682"
},
{
"sellingPrice": "95.00",
"inStock": "10",
"discount": "5%",
"name": "School Shirt Blue",
"code": "SKITO293949495",
"warehouseId": "723468998682"
}
]
}
I want to change just one of the products stock value
{
"sellingPrice": "95.00",
"inStock": "10",
"discount": "5%",
"name": "School Shirt Blue",
"code": "SKITO293949495",
"warehouseId": "723468998682"
}
Like update store product stock less 1 where store id = x, something to this effect
FOR store IN stores
FILTER store._key == "837108415472"
FOR product IN store.products
FILTER product.code == "SKITO293949495"
UPDATE product WITH { inStock: (product.inStock - 1) } IN store.products
Apart from the above possibly it makes sense to store product as a separate document in collection store_products. I believe in NOSQL that is the best approach to reduce document size.
Found answer
here arangodb-aql-update-single-object-in-embedded-array and there
arangodb-aql-update-for-internal-field-of-object
I however believe it is best to maintain separate documents and rather use joins when retrieving. Updates easily

how to prevent to customer to add same credit card

I am using stripe as my payment provider and storing encrypted credit card id in my db returned from stripe.
My question is that from GUI customer can add same card again. I see stripe do not prevent to add same card multiple time for same customer. Since stripe always generates different encrypted card id for same card so I can't use it to validate if same card is being added again.
How can stop customer to add same card again again.
Looks like I got that . I can use fingerprint returned in json response. I saw stripe dashboard and found that fingerprint is always same for same card which I was adding again again.
Here is json request and response to confirm
Request
{
"source": {
"number": "378282246310005",
"cvc": "123",
"address_line2": "4th Floor",
"address_line1": "140 2nd Street",
"address_country": "USA",
"name": "VIAY KUMAR",
"address_state": "CA",
"exp_month": 12,
"exp_year": 2015,
"address_zip": "94105",
"address_city": "San Francisco",
"object": "card"
}
}
Response
{
"id": "card_166H9rC8Y8JrMFgBh9GVsmNG",
"object": "card",
"status": null,
"exp_month": 12,
"exp_year": 2015,
"last4": "0005",
"country": "US",
"type": null,
"name": "VIAY KUMAR",
"customer": "cus_6IrxhfwXNyD1Uw",
"recipient": null,
"address_line1": "140 2nd Street",
"address_line2": "4th Floor",
"address_zip": "94105",
"address_city": "San Francisco",
"address_state": "CA",
"address_country": "USA",
"address_zip_check": "pass",
"address_line1_check": "pass",
"cvc_check": "pass",
"fingerprint": "TwjSA2KqPDhSMUvQ",
"brand": "American Express",
"funding": "credit"
}
added same card again and got different card id but same finger print :-)
Request
{
"source": {
"number": "378282246310005",
"cvc": "123",
"address_line2": "4th Floor",
"address_line1": "140 2nd Street",
"address_country": "USA",
"name": "VIAY KUMAR",
"address_state": "CA",
"exp_month": 12,
"exp_year": 2015,
"address_zip": "94105",
"address_city": "San Francisco",
"object": "card"
}
}
Response
{
"id": "card_166HKVC8Y8JrMFgBfvbHPgk2",
"object": "card",
"status": null,
"exp_month": 12,
"exp_year": 2015,
"last4": "0005",
"country": "US",
"type": null,
"name": "VIAY KUMAR",
"customer": "cus_6IrxhfwXNyD1Uw",
"recipient": null,
"address_line1": "140 2nd Street",
"address_line2": "4th Floor",
"address_zip": "94105",
"address_city": "San Francisco",
"address_state": "CA",
"address_country": "USA",
"address_zip_check": "pass",
"address_line1_check": "pass",
"cvc_check": "pass",
"fingerprint": "TwjSA2KqPDhSMUvQ",
"brand": "American Express",
"funding": "credit"
}
Thanks to Vijay for the above answer.
I've written the following Ruby code in my Rails app to check for this.
Replace the relevant #user.stripe_customer_id variable with your own.
# Retrieve the customer we're adding this token to
customer = Stripe::Customer.retrieve(#user.stripe_customer_id)
# Retrieve the token
token = Stripe::Token.retrieve(params[:stripeToken])
# The fingerprint of the card is stored in `card.fingerprint`
card_fingerprint = token.card.fingerprint
# Check if the card fingerprint submitted matches one of the customer's current sources
fingerprint_already_exists = customer.sources.any? {|source| source[:fingerprint] == card_fingerprint}
if fingerprint_already_exists
# You can do whatever you want here. I've personally set a flash message to let the user know this card is already on their account
flash[:warning] = "That card already exists on your account."
redirect_to user_path(#user) and return
end
# Continue adding the source as normal
customer.sources.create(source: params[:stripeToken])
# Anything else you want to do...
flash[:success] = "Your account has been updated."
redirect_to user_path(#user) and return
The fingerprint generated by Stripe is unique to each card. As taken from the docs:
fingerprint string
Uniquely identifies this particular card number. You can use this attribute to check whether two customers who’ve signed up with you are using the same card number, for example.
Assuming you already have a customer object at this point (either a new one or one to update), this will let you add a card and make it default, without duplicates:
// $customer = \Stripe\Customer::retrieve( $clicker->customer );
/**
* Add the card, but only if it does not exist. Make it default in any case.
**/
$token = \Stripe\Token::retrieve( $_POST['stripeToken'] );
$card = null;
/** Does this customer already have this card? If so, find it. **/
foreach ( $customer->sources['data'] as $source ) {
if ( $source['fingerprint'] == $token['card']->fingerprint ) {
$card = $source;
}
}
/** If not, add the new card to the customer **/
if ( is_null( $card ) ) {
$card = $customer->sources->create( array( 'source' => $_POST['stripeToken'] ) );
}
$customer->default_source = $card->id;
$customer->save();
You'd enclose this in the usual try/catch as exemplified by the docs.
That being said, from the point of view of the user, it will be better, if possible, to show them a list of their cards (last4 + expire date) and let them pick the one they'd like to charge – instead of asking for their info needlessly.

Resources