We have a web page which takes a Stripe payment, once the payment is complete Stripe can call a webhook on our server.
At this point, we can mark an Order as complete and complete any other additional tasks.
How can we have the order webpage update/move the user onto to order complete?
Should we consistently hit the server in AJAX to check if it's now complete, or is there a better way of doing this.
Q: How can we have the order webpage update/move the user onto to order complete?
Most payment engines will redirect the payment session to a URL of your choosing with a result code or a different URL per result code. These can generally be configured at the moment the request is being made or for the entire site in a general configuration. These results should not be relied on for the actual payment as that is the job for the web hook. They can be trusted enough for your site to show a general success/fail error message and let the user continue doing whatever.
Stripe also allows for this, you can specify a success_url (or successUrl in the client integration).
See Create a Checkout Session on your server for how to pass this URL to the request. You can also include a cancel_url. See the last 2 parameters in the code sample below:
curl https://api.stripe.com/v1/checkout/sessions \
-u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
-d payment_method_types[]=card \
-d line_items[][name]=T-shirt \
-d line_items[][description]="Comfortable cotton t-shirt" \
-d line_items[][images][]="https://example.com/t-shirt.png" \
-d line_items[][amount]=500 \
-d line_items[][currency]=usd \
-d line_items[][quantity]=1 \
-d success_url="https://example.com/success" \
-d cancel_url="https://example.com/cancel"
See also Checkout Purchase Fulfillment.
When your customer successfully completes their payment or initiates a subscription using Checkout, Stripe redirects them to the URL that you specified in the success_url parameter (or successUrl in the client integration). Typically, this is a page on your website that informs your customer that their payment was successful.
And as I stated above do not rely on this as the actual indicator if the payment succeeded. You should use the web hooks for that.
Do not rely on the redirect to the success_url alone for fulfilling purchases as:
Malicious users could directly access the success_url without paying and gain access to your goods or services.
Customers may not always reach the success_url after a successful payment. It is possible they close their browser tab before the redirect occurs.
Good question,
You can handle the stripe payment result to take a new effect on your page
var cardholderName = document.getElementById('cardholder-name');
var cardButton = document.getElementById('card-button');
var clientSecret = cardButton.dataset.secret;
cardButton.addEventListener('click', function(ev) {
stripe.handleCardPayment(
clientSecret, cardElement, {
payment_method_data: {
billing_details: {name: cardholderName.value}
}
}
).then(function(result) {
if (result.error) {
// Display error.message in your UI.
} else {
// The payment has succeeded. update your front-end
}
});
});
Should we consistently hit the server in AJAX to check if it's now
complete, or is there a better way of doing this.
An Ajax example is here but beter way to doing that is the fetch api. You can find out all detail in here
Should we consistently hit the server in AJAX to check if it's now complete, or is there a better way of doing this.
No you shouldn't and yes there is a better way. Callback pages/webhooks would make sense if you didn't have an asp.net server handing the transaction, but they aren't necessary here.
How can we have the order webpage update/move the user onto to order
complete?
The stripe payment process only takes a couple seconds to respond with a status code. It's not the same as Paypal where the user is directed to a Paypal site and then back to your site.
The process is supposed to go:
The user enters their payment information into stripe generated
elements on your page.
Stripe gives your front end javascript a
token that represents the customer's payment data.
You post that information to your server using ajax or even a regular old fashioned form request.
The server side script handling the call uses the asp.net stripe library to send the payment and gets an answer back like the one below.
Save the transaction result to your database as needed.
a. If the stripe resonse includes "status":"succeeded" then you can serve the customer with a new page with the paid receipt.
b. If it failed for some reason you can reload the payment page and use the "failure_message" to tell the customer why their card is no good.
Let the user wait until stripe replies with a message regarding the success or failure of the payment and send him because it only takes a second.
/* SAMPLE RESPONSE FROM STRIPE
{
"id": "ch_1D658SDJ46dzUiasdfsdfaDq",
"object": "charge",
"amount": 2125,
"amount_refunded": 0,
"application": null,
"application_fee": null,
"balance_transaction": "txn_1D658SDJ46dzUilftNXRCz64",
"captured": true,
"created": 1565431460,
"currency": "usd",
"customer": null,
"description": "856 addresses",
"destination": null,
"dispute": null,
"failure_code": null,
"failure_message": null,
"fraud_details": {},
"invoice": null,
"livemode": false,
"metadata": {},
"on_behalf_of": null,
"order": null,
"outcome": {
"network_status": "approved_by_network",
"reason": null,
"risk_level": "normal",
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"receipt_email": null,
"receipt_number": null,
"refunded": false,
"refunds": {
"object": "list",
"data": [],
"has_more": false,
"total_count": 0,
"url": "/v1/charges/ch_1D658SDJ46dzUilfalFFraDq/refunds"
},
"review": null,
"shipping": null,
"source": {
"id": "card_1D658RDJ46dzUilfbkLSOIwp",
"object": "card",
"address_city": "test",
"address_country": "US",
"address_line1": "123 test",
"address_line1_check": "pass",
"address_line2": "",
"address_state": null,
"address_zip": "32121",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": null,
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 12,
"exp_year": 2033,
"fingerprint": "fNMgYIntTkOnLVzk",
"funding": "credit",
"last4": "4242",
"metadata": {},
"name": "Test",
"tokenization_method": null
},
"source_transfer": null,
"statement_descriptor": null,
"status": "succeeded",
"transfer_group": null
}
Related
I'm looking to implement a call system that supports call transfer on our 'softphone' built using the Voice SDk, and frankly, I'm overwhelmed by the numerous articles on this but most are outdated (early 2015) or not just working for some reason.
My code involves initiating calls as a conference so warm transfer can be utilized. Hence, I'll demonstrate one side of the call (incoming) for this example.
Lead calls one of the sales person on our app, say SalesPerson A, SpA for short.
SpA would like, probably even before picking the call, transfer it to SpB on the same app.
I'm using each sales person fullname as Identity with every token (return jsonify(identity=fetch_user_fullname(), token=token.to_jwt().decode()), and call transfer is only applicable to all online sales persons.
#app.route('/call', methods=['POST'])
def inbound():
call_sid = flask.request.values.get('CallSid')
response = VoiceResponse()
response.dial().conference(call_sid)
call = client.calls.create(to='client:salespersonA',
from_='twilio_number_called_by_lead',
url = BASE_URL + '/conf/' + call_sid)
return Response(str(response), mimetype='application/xml')
#app.route('/conf/<conference_name>', methods=['GET', 'POST'])
def conference_line(conference_name):
response = VoiceResponse()
response.dial(hangupOnStar=True).conference(conference_name)
response.gather(action=BASE_URL + '/add-agent/' + conference_name,
numDigits=1)
return Response(str(response), 200, mimetype="application/xml")
#app.route('/add-agent/<conference_name>', methods=['POST'])
def add_second_agent(conference_name):
client.calls.create(to='client:salespersonB', from_='twilio_number_called_by_lead',
url=BASE_URL + '/conference/' + conference_name)
response = VoiceResponse()
response.dial(hangupOnStar=True).conference(conference_name)
return Response(str(response), 200, mimetype="application/xml")
My problem with this is since a conference call is initiated when a salesperson answers the line, that associated twilio account is billed (I would have like that caller gets billed only) - due to my twilio number initiating conference call to salespersonA
Also, my issue is most of these holders have a null value and that when lead calls and the conference is initiated, the caller ID to our salespersonA is the twilio number lead dialed, I would have expected the caller ID to be the lead's contact.
Response: 201 {"date_updated": null, "price_unit": "USD", "parent_call_sid": null, "caller_name": null, "duration": null, "from": "twilio_number_called_by_lead", "to": "client:salespersonA", "annotation": null, "answered_by": null, "sid": "CA04...", "queue_time": "0", "price": null, "api_version": "2010-04-01", "status": "queued", "direction": "outbound-api", "start_time": null, "date_created": null, "from_formatted": "twilio_number_called_by_lead_formatted", "group_sid": null, "trunk_sid": null, "forwarded_from": null, "uri": "/2010-04-01/Accounts/AC6../Calls/CA04....json", "account_sid": "AC6", "end_time": null, "to_formatted": "LABEL-9EQk7FJ", "phone_number_sid": null, "subresource_uris": {"feedback": "/2010-04-01/Accounts/AC6/Calls/CA04.../Feedback.json", "notifications": "/2010-04-01/Accounts/AC6/Calls/CA04.../Notifications.json", "recordings": "/2010-04-01/Accounts/AC6.../Calls/CA04.../Recordings.json", "streams": "/2010-04-01/Accounts/AC6.../Calls/CA04.../Streams.json", "payments": "/2010-04-01/Accounts/AC6.../Calls/CA04.../Payments.json", "siprec": "/2010-04-01/Accounts/AC6.../Calls/CA04.../Siprec.json", "events": "/2010-04-01/Accounts/AC6.../Calls/CA04.../Events.json", "feedback_summaries": "/2010-04-01/Accounts/AC6.../Calls/FeedbackSummary.json"}}
This implementation uses keypad to transfer the call, I'm looking to use a button. And Gather does not listen to buttons so I'm lost.
call_sid: CA044876bcd8b74071f9bf9daec3bbae01
I am currently doing POC(proof of concept) on IVR loadtesting where I just want to call a IVR and have no interest in sound quality and all. So I come across twilio rest api which can make a outbound call.
It is working perfectly with python but I want to use it with loadrunner as it support rest api. I searched for twilio api urls and key value combinations. but hard luck for this. can anyone provide me the required URL and key value arrangement. or can guide me how to get those.
thanks in advance.
The documentation, Making Calls, has some code examples and example responses. You can make an API call using Postman (POST via x-www-form-urlencoded) and see the key:value pairs in the returned JSON, as shown below. API Explorer in Twilio Console is also useful for that.
{
"date_updated": null,
"price_unit": "USD",
"parent_call_sid": null,
"caller_name": null,
"duration": null,
"from": "+15095550100",
"to": "+14075550100",
"annotation": null,
"answered_by": null,
"sid": "CAaacc78574ae1b9d2bf483f0123456789",
"queue_time": "0",
"price": null,
"api_version": "2010-04-01",
"status": "queued",
"direction": "outbound-api",
"start_time": null,
"date_created": null,
"from_formatted": "(509) 555-0100",
"group_sid": null,
"trunk_sid": null,
"forwarded_from": null,
"uri": "/2010-04-01/Accounts/ACdeca5d479509eeb8beaba0123456789/Calls/CAaacc78574ae1b9d2bf483f0123456789.json",
"account_sid": "ACdeca5d479509eeb8beaba0123456789",
"end_time": null,
"to_formatted": "(407) 555-0100",
"phone_number_sid": "PN0b9c2733e2a9ad0c98352b0123456789",
"subresource_uris": {
"notifications": "/2010-04-01/Accounts/ACdeca5d479509eeb8beaba0123456789/Calls/CAaacc78574ae1b9d2bf483f0123456789/Notifications.json",
"recordings": "/2010-04-01/Accounts/ACdeca5d479509eeb8beaba0123456789/Calls/CAaacc78574ae1b9d2bf483f0123456789/Recordings.json",
"feedback": "/2010-04-01/Accounts/ACdeca5d479509eeb8beaba0123456789/Calls/CAaacc78574ae1b9d2bf483f0123456789/Feedback.json",
"payments": "/2010-04-01/Accounts/ACdeca5d479509eeb8beaba0123456789/Calls/CAaacc78574ae1b9d2bf483f0123456789/Payments.json",
"feedback_summaries": "/2010-04-01/Accounts/ACdeca5d479509eeb8beaba0123456789/Calls/FeedbackSummary.json"
}}
I am trying to create the schema for Message API
As per the documentation, the sample response properties for reaction provided are below
Documentation sample response
"reactions": [
{
"reactionType": "like",
"createdDateTime": "2019-01-21T19:55:51.893Z",
"user": {
"application": null,
"device": null,
"conversation": null,
"user": {
"id": "e1ecb745-c10f-40af-a9d4-cab946c80ac7",
"displayName": null,
"userIdentityType": "aadUser"
}
}
}
]
From the documentation user is Identity type identity set
Identity is of type:
{
"displayName": "string",
"id": "string",
"tenantId": "string",
"thumbnails": { "#odata.type": "microsoft.graph.thumbnailSet" }
}
From the sample response as well as the response from endpoint, tenantId is not present.
There is a difference in sample response/actual endpoint response and documented properties:
The one with tenantId or one without tenantId.
The user is 1 level as per property documentation but as per actual response and sample response user property has user with in.
What is the correct schema of reaction property that we should consider, because we see variation in documentation vs actual response ?
ok, I think I understand - you're just asking what you should be coding for / expecting, when you query the api. It looks to me like the first link you've posted is the more correct, but you can verify this by using the Graph Explorer. This response does NOT bring back "tenantId", but you haven't explained if you -need- tenantId. If so, there are other ways to get it.
#KritikaVohra, Consider the response that you receive from the https://graph.microsoft.com/beta/teams/{id}/channels/{id}/messages. You don't need tenant id here. in case in conversation if you need it, you can use it from turnContext.
I followed the official rest-api documentation of sylius but couldn't create the user with field user[authorizationRoles]. Since role_user is default role, i provided arrays of roles as mentioned in docs like this
POST http://localhost:8000/api/customers/
firstName = Ram
lastName = Thakuri
email = ram#yahoo.com
gender = m
user[plainPassword] = ******
user[authorizationRoles] = [ROLE_API_ACCESS]
I even searched in similar posts but couldn't found right answer, don't know where i am wrong but got validation failed message and errors as below (i am using POSTMAN).
{
"code": 400,
"message": "Validation Failed",
"errors": {
"errors": [
"This form should not contain extra fields."
],
"children": {
"firstName": {},
"lastName": {},
"email": {},
"birthday": {},
"gender": {},
"phoneNumber": {},
"subscribedToNewsletter": {},
"group": {},
"user": {
"children": {
"plainPassword": {},
"enabled": {}
}
}
}
}
}
I want to receive an access token using an OAUTH for every registered user to have an api access.
I am newbie to sylius so please help me out on this.
Thanks in advance
You are not able to do it out-of-the-box. The endpoint you are trying to use is related to customers, therefore setting authorization roles has been removed. This part of the documentation is outdated. You can open a PR with the fix, if you want :)
Anyway, it will be possible to do it with the PR #7711 which will allow managing SyliusUsers but through /users/ endpoint which will not create a customer.
The best solution for you would be to customise Sylius\Bundle\CoreBundle\Form\Type\User\ShopUserType and add that field to FormType. Just take a look at the PR I have mentioned before.
Just as a warning, I want to stress, that ShopApi is an experimental concept for Sylius, so you can meet a lot more complex problems if you want to use it this way. It is doable, but not trivial.
I followed this guide: http://keystone.openstack.org/api_curl_examples.html
and it seemed that I got a valid token by ran:
curl -d '{"auth":{"passwordCredentials":{"username": "can", "password": "mypassword"}}}' -H "Content-type: application/json" http://url:35357/v2.0/tokens
and it returned:
{
"access":
{
"token":
{
"expires": "2012-05-21T14:35:17Z",
"id": "468da447bd1c4821bbc5def0498fd441"
},
"serviceCatalog": {},
"user":
{
"username": "can",
"roles_links": [],
"id": "bb6d3a09ad0c4924bf20c1a32ccb5781",
"roles": [],
"name": "can"
}
}
}
but when I came to the next few sections to validate this token, I encountered this magic number: X-Auth-Token:999888777666. At first I thought it's the token I got but I was wrong.
I think I may have missed something, so I read related sections in openstack documents( http://keystone.openstack.org/configuration.html and http://docs.openstack.org/api/openstack-compute/programmer/content/ ), but still no idea how the number comes from.
could anyone explain to me
what's the meaning of that magic number
how to get the right value of it so I can get a working token to manage other parts of openstack
That magic number (string really) is the admin_token setting in your keystone.conf file. Under the [DEFAULT] section in keystone.conf set
admin_token = abcd1234
If you don't use it for admin actions, you'll see something like
ubuntu#i-000004bc:~/devstack$ curl http://localhost:35357/v2.0/tenants
{"error": {"message": "The request you have made requires authentication.", "code": 401, "title": "Not Authorized"}}
If you do use it, you'll see something like
ubuntu#i-000004bc:~/devstack$ curl -H "X-Auth-Token: abcd1234" http://localhost:35357/v2.0/tenants
{"tenants_links": [], "tenants": [{"enabled": true, "description": null, "name": "demo", "id": "aee8a46babcb4e4286021c8f6ef996cd"}, {"enabled": true, "description": null, "name": "invisible_to_admin", "id": "de17fea45de148ada0a58e998e6c3e73"}, {"enabled": true, "description": null, "name": "admin", "id": "f34b0c8ab30e450489b121fbe723fde5"}, {"enabled": true, "description": null, "name": "service", "id": "fbe3e2e530fd47298cb2cba1b4afa3da"}]}
To get the list of tenants, in our current implementation, we authenticate with admin credentials and use the token returned to get list of tenants.
The implementation works smooth with the authentication token. It may work with admin_token but I have not verified.
If you see the examples you are referring to, there are 2 types of endpoints used
Endpoint pointing to port 5000 - public port
Endpoint pointing to port 35357 - admin port
In examples which are hitting admin port you would need to specify the "X-Auth-Token" header as the admin_token (specified in the keystone.conf file)
The token itself is in dict["access"]["token"]["id"] which is that part that will go in the header of subsequent HTTP requests, i.e
X-Auth-Token: 468da447bd1c4821bbc5def0498fd441
The value 999888777666 is from the curl example tutorial and will definitely not work.
As for the value of the token itself, it's randomly generated by the OpenStack service and shouldn't contain any useful information from your point of view.
(BTW, you probably shouldn't go pasting the tokens into forums as they're valid for 24 hours and anyone with a copy of the token and access to your compute endpoint can use it to impersonate you).