I am developing a webapp using rails 3.2.
I am trying to build a callback method for Paymill that will be used to catch Transaction success events.
This is my controller. It´s very simple and it works fine when I make a simulated POST request using either CURL or a Firefox plugin and using the JSON body that Paymill documentation states is the correct one.
Unfortunately when using Paymills own test script (made in PHP) it failes.
class Admin::TransactionsController < ActionController::Base
def create
transaction = Transaction.new
transaction.client_id = params[:event][:event_resource][:client][:id]
transaction.trans_id = params[:event][:event_resource][:id]
transaction.amount = params[:event][:event_resource][:amount]
transaction.currency = params[:event][:event_resource][:currency]
transaction.save
render :nothing => true
end
end
This is the JSON body that the documentation says it will attach to callback event:
{
"event": {
"event_type": "transaction.succeeded",
"event_resource": {
"id": "tran_d06aae1df72af329c39367cde9ed19",
"amount": "12345",
"origin_amount": 12345,
"status": "closed",
"description": "test paymill",
"livemode": false,
"refunds": null,
"currency": "USD",
"created_at": 1375457696,
"updated_at": 1375457696,
"response_code": 20000,
"short_id": null,
"is_fraud": false,
"invoices": [],
"app_id": null,
"fees": [],
"payment": {
"id": "pay_46ee3be859eedb72d325adcb6",
"type": "creditcard",
"client": "client_d94e1e3efbc59073629df",
"card_type": "visa",
"country": null,
"expire_month": "1",
"expire_year": "2014",
"card_holder": null,
"last4": "1111",
"created_at": 1375457695,
"updated_at": 1375457696,
"app_id": null
},
"client": {
"id": "client_d941e3efbc59e073629df",
"email": null,
"description": null,
"created_at": 1375457696,
"updated_at": 1375457696,
"app_id": null,
"payment": [],
"subscription": null
},
"preauthorization": null
}
}
}
When making the request with the PHP test script the body arrives in this shape
and Rails throughs errors:
string(1712) ""{\n \"event\": {\n \"event_type\": \"transaction.succeeded\",\n \"event_resource\": {\n \"id\": \"tran_d06aae1f72af329c39367cde9ed19\",\n \"amount\": \"12345\",\n \"origin_amount\": 12345,\n \"status\": \"closed\",\n \"description\": \"test paymill\",\n \"livemode\": false,\n \"refunds\": null,\n \"currency\": \"USD\",\n \"created_at\": 1375457696,\n \"updated_at\": 1375457696,\n \"response_code\": 20000,\n \"short_id\": null,\n \"is_fraud\": false,\n \"invoices\": [],\n \"app_id\": null,\n \"fees\": [],\n \"payment\": {\n \"id\": \"pay_46ee3b85f9eedb72d325adcb6\",\n \"type\": \"creditcard\",\n \"client\": \"client_d941e3effbc59073629df\",\n \"card_type\": \"visa\",\n \"country\": null,\n \"expire_month\": \"1\",\n \"expire_year\": \"2014\",\n \"card_holder\": null,\n \"last4\": \"1111\",\n \"created_at\": 1375457695,\n \"updated_at\": 1375457696,\n \"app_id\": null\n },\n \"client\": {\n \"id\": \"client_d941e3efbc59073629df\",\n \"email\": null,\n \"description\": null,\n \"created_at\": 1375457696,\n \"updated_at\": 1375457696,\n \"app_id\": null,\n \"payment\": [],\n \"subscription\": null\n },\n \"preauthorization\": null\n }\n }\n}""
The error I get from Rails is this now:
Error occurred while parsing request parameters
NoMethodError - undefined method `each' for #<String:0x007fc820a1fc08>:
What is going on? It´s like Rails treats this body like faulty text? If I remove this line from the PHP (and thus does not JSON encode the body before sending) it works fine and I get no errors. And it doesn´t matter if I the create method is empty. Something is happening before this method gets called?
json_encode($http_body);
Thankful for all help! I will soon start to cry.
Where did you get the test script from? The one I have here, does contain the body in plain text and so it does not need json encoding anymore, this should work (replace <YOUR_TARGET_URL> with your URL):
<?php
$http_body = '{
"event" : {
"event_type" : "transaction.succeeded",
"event_resource" :
{"id":"__TRANSACTION_ID__","amount":"12345","origin_amount":12345,"status":"closed","description":"test paymill","livemode":false,"refunds":null,"currency":"SEK","created_at":1375457696,"updated_at":1375457696,"response_code":20000,"short_id":null,"is_fraud":false,"invoices":[],"app_id":null,"fees":[],"payment":{"id":"__PAYMNET_ID__","type":"creditcard","client":"__CLIENT_ID__","card_type":"visa","country":null,"expire_month":"1","expire_year":"2014","card_holder":null,"last4":"1111","created_at":1375457695,"updated_at":1375457696,"app_id":null},"client":{"id":"__CLIENT_ID__","email":null,"description":null,"created_at":1375457696,"updated_at":1375457696,"app_id":null,"payment":[],"subscription":null},"preauthorization":null}
}
}';
$curl = curl_init();
$curlOpts = array(
CURLOPT_URL => '',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSLVERSION => 3,
CURLOPT_TIMEOUT => 60,
CURLOPT_CONNECTTIMEOUT => 60,
CURLOPT_HTTPHEADER => array('Content-type: application/json'),
CURLOPT_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
CURLOPT_MAXREDIRS => 5
);
$curlOpts[CURLOPT_URL] = '<__YOUR_TARGET_URL__>';
$curlOpts[CURLOPT_POSTFIELDS] = $http_body;
curl_setopt_array($curl, $curlOpts);
$result = curl_exec($curl);
$responseInfo = curl_getinfo( $curl );
var_dump($responseInfo);
var_dump($result);
curl_close($curl);
exit;
Related
I am making a post request in react-native using apisauce, but the request is too slow. The request takes around 1000ms in Postman, but is slower in react-native. How can I optimize this?
My sample response data is like
[
{
"email": "abc#gmail.com",
"id": 2753,
"phone_number": "",
"user_name": "New client"
},
{
"email": "cda#gmail.com",
"id": 2754,
"phone_number": "",
"user_name": "New client"
},
{
"email": "dsa#gmail.com",
"id": 8868,
"phone_number": "",
"user_name": "Slow"
}
]
And the program for post request is:
const setConfigHeader = () =>
api.setHeader(
'Authorization',
getState().login.data.access_token
? `Bearer ${getState().login.data.access_token}`
: null,
);
const getAddressBookData = data =>
api.post(globalConstants.user_address_book, data, setConfigHeader());
I currently have a problem with the prestashop API.
I'm trying to update the amount of a combination of a product.
<?php
$request = new HttpRequest();
$request->setUrl('https://myurl.com/api/combinations/15544');
$request->setMethod(HTTP_METH_PUT);
$request->setQueryData(array(
'io_format' => 'JSON'
));
$request->setHeaders(array(
'cache-control' => 'no-cache',
'Connection' => 'keep-alive',
'Accept-Encoding' => 'gzip, deflate',
'Host' => 'myurl.com',
'Cache-Control' => 'no-cache',
'Accept' => '*/*',
'User-Agent' => 'PostmanRuntime/7.19.0',
'Authorization' => 'Basic HIDDEN',
'Content-Type' => 'application/xml'
));
$request->setBody('<?xml version="1.0" encoding="UTF-8"?>
<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
<combination>
<id>15544</id>
<quantity>105</quantity>
<location></location>
<ean13></ean13>
<isbn></isbn>
<upc></upc>
<upplier_reference></upplier_reference>
<wholesale_price></wholesale_price>
<price></price>
<weight></weight>
<unit_price_impact></unit_price_impact>
<minimal_quantity>1</minimal_quantity>
<minimal_quantity>1</minimal_quantity>
<id_product>195</id_product>
<reference>E1903XLN</reference>
</combination>
</prestashop>');
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
The response from the server is correct.
When I get the declination with a get here is the return:
{
"combination": {
"id": 15544,
"id_product": "195",
"location": "",
"ean13": "",
"isbn": "",
"upc": "",
"quantity": "105",
"reference": "E1903XLN",
"supplier_reference": "",
"wholesale_price": "0.000000",
"price": "0.000000",
"ecotax": "0.000000",
"weight": "0.000000",
"unit_price_impact": "0.000000",
"minimal_quantity": "1",
"low_stock_threshold": null,
"low_stock_alert": "0",
"default_on": null,
"available_date": "0000-00-00",
"associations": {
"product_option_values": [
{
"id": "28"
},
{
"id": "32"
}
]
}
}
}
Nevertheless on prestashop in the backoffice I do not see the changes:
Image of the BO
Do you have an idea or solution ?
Thanks a lot for your help
To set an update of stock quantity for your combination you need to talk with the object StockAvailable.
Have a nice day :) !
I'm having some trouble finding how to intercept Stripe webhook calls in my application. I use graphql-yoga (express) and prisma.
I have to listen to payment failure calls from Stripe so I can edit the corresponding user profile.
Thanks for the help!
Stripe webhook calls look like so :
{
"created": 1326853478,
"id": "charge.expired_00000000000000",
"type": "charge.expired",
"object": "event",
"request": null,
"pending_webhooks": 1,
"data": {
"object": {
"id": "ch_00000000000000",
"object": "charge",
"amount": 100,
"captured": false,
"created": 1537153592,
"currency": "usd",
"customer": null,
"description": "My First Test Charge (created for API docs)",
"invoice": null,
"livemode": false,
"on_behalf_of": null,
"order": null,
"outcome": null,
"paid": true,
"receipt_email": null,
"receipt_number": null,
"refunded": false,
"review": null,
"shipping": null,
"source": {
"id": "card_00000000000000",
"object": "card",
"address_city": null,
"address_country": null,
"address_line1": null,
"address_line1_check": null,
"address_line2": null,
"address_state": null,
"address_zip": "12919",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_00000000000000",
"cvc_check": null,
"name": null,
"tokenization_method": null
},
"statement_descriptor": null,
"status": "succeeded",
}
}
}
Since Stripe Webhook returns a generic http POST with JSON payload, it will not format the event data according to Graphql language query.
For now, what you can do is to expose a normal REST API endpoint using Graphql-Yoga's express[0]
I have composed a working sample code you can try it out
const { GraphQLServer } = require('graphql-yoga')
const typeDefs = `
type Query {
hello(name: String): String!
}
`
const resolvers = {
Query: {
hello: (_, { name }) => `Hello ${name || 'World'}`,
},
}
const server = new GraphQLServer({ typeDefs, resolvers, skipValidation: true })
server.express.use('/api/stripe/webhooks', (req, res) => {
// Handle your callback here !!!!
res.status(200).send();
})
server.start(() => console.log('Server is running on localhost:4000'))
Let me know if the above helps.
[0] https://github.com/prisma/graphql-yoga#how-to-eject-from-the-standard-express-setup
Call
GET https://graph.microsoft.com/beta/managedDevices/dd9615c4-9d3b-4ece-9272-34a10e8fe908/
RESPONSE
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#managedDevices/$entity",
"id": "dd9615c4-9d3b-4ece-9272-34a10e8fe908",
"userId": null,
"deviceName": "iPad Feb23",
"hardwareInformation": {
"serialNumber": null,
"totalStorageSpace": 0,
"freeStorageSpace": 0,
"imei": "",
"meid": null,
"manufacturer": null,
"model": null,
"phoneNumber": null,
"subscriberCarrier": null,
"cellularTechnology": null,
"wifiMac": null,
"operatingSystemLanguage": null,
"isSupervised": false,
"isEncrypted": false,
"isSharedDevice": false,
"sharedDeviceCachedUsers": []
},
"ownerType": "personal",
"deviceActionResults": [],
"managementState": "managed",
"enrolledDateTime": "2017-05-24T13:10:20.8964572Z",
"lastSyncDateTime": "2017-05-24T15:16:02.6465376Z",
"chassisType": "tablet",
"operatingSystem": "iOS",
"deviceType": "iPad",
"complianceState": "compliant",
"jailBroken": "False",
"managementAgents": 2,
"managementAgent": "mdm",
"osVersion": "9.3.5",
"easActivated": false,
"easDeviceId": null,
"easActivationDateTime": "0001-01-01T00:00:00Z",
"aadRegistered": null,
"enrollmentType": "userEnrollmentWithServiceAccount",
"lostModeState": "disabled",
"activationLockBypassCode": null,
"emailAddress": null,
"azureActiveDirectoryDeviceId": "00000000-0000-0000-0000-000000000000",
"deviceRegistrationState": "registered",
"deviceCategoryDisplayName": null,
"isSupervised": false,
"exchangeLastSuccessfulSyncDateTime": "0001-01-01T00:00:00Z",
"exchangeAccessState": "none",
"exchangeAccessStateReason": "none",
"remoteAssistanceSessionUrl": "",
"isEncrypted": false,
"model": null,
"manufacturer": null
}
But when i try to do post nothing seems to work ... according to the doc here https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/api/intune_mam_mobileappidentifierdeployment_create
it should work just fine what is the problem with this call ...?
Call
POST https://graph.microsoft.com/beta/managedDevices/dd9615c4-9d3b-4ece-9272-34a10e8fe908/deviceCompliancePolicyStates/
{
"#odata.type": "#microsoft.graph.deviceCompliancePolicyState",
"settingStates": [
{
"#odata.type": "microsoft.graph.deviceCompliancePolicySettingState",
"setting": "Setting value",
"instanceDisplayName": "Instance Display Name value",
"state": "notApplicable",
"errorCode": 9,
"errorDescription": "Error Description value",
"userPrincipalName": "User Principal Name value",
"sources": [
{
"#odata.type": "microsoft.graph.settingSource",
"id": "Id value",
"displayName": "Display Name value"
}
]
}
],
"displayName": "Display Name value",
"version": 7,
"platformType": "androidForWork",
"state": "notApplicable",
"settingCount": 12
}
RESPONSE
{
"error": {
"code": "No method match route template",
"message": "No OData route exists that match template ~/entityset/key/navigation with http verb POST for request /StatelessDeviceConfigurationFEService/managedDevices('dd9615c4-9d3b-4ece-9272-34a10e8fe908')/deviceCompliancePolicyStates.",
"innerError": {
"request-id": "544c4ee2-a6de-4203-9c30-c3e589b77713",
"date": "2017-05-24T15:48:30"
}
}
}
I'm an engineer on the Microsoft Intune team specifically working on the integration between Microsoft Graph and Microsoft Intune.
In this case it looks like there is an issue with the documentation as deviceCompliancePolicyState entity can not be created, it is read-only entity that shows the state of a device compliance policy. I will work to get the documentation corrected. If you can let me know what scenario you were trying to accomplish by creating a deviceCompliancePolicyState entity I may be able to point you in the right direction.
Hope that helps
Peter
When I viewed the documentation for the "Update View" endpoint there was very little information available (see https://developers.podio.com/doc/views/update-view-20069949). The current documentation states that the endpoint accepts one parameter,
view_id but it seems that an API consumer would also want to be able to supply additional details to modify the view's definition.
Is there any example code available to demonstrate how this endpoint should be used?
The Podio Ruby client provides code that uses this endpoint. If you take a look here you can see that the endpoint expects a JSON body to be supplied in the PUT that specifies the new view's definition. In the Ruby code it's referred to as "attributes" and this is consistent with the API documentation for the other View operations. Here is an example HTTP request:
PUT /view/31011898 HTTP/1.1
Host: api.podio.com
Authorization: OAuth2 your_oauth2_token_here
Content-Type: application/json
Cache-Control: no-cache
{
"layout": "table",
"name": "SPAM",
"rights": [
"delete",
"view",
"update"
],
"fields": {},
"sort_desc": false,
"created_by": {
"user_id": <creator user id>,
"space_id": null,
"image": {
"hosted_by": "podio",
"hosted_by_humanized_name": "Podio",
"thumbnail_link": "https://d2cmuesa4snpwn.cloudfront.net/public/",
"link": "https://d2cmuesa4snpwn.cloudfront.net/public/",
"file_id": <some file id>,
"external_file_id": null,
"link_target": "_blank"
},
"profile_id": <profile id>,
"org_id": null,
"link": "https://podio.com/users/<user id>",
"avatar": <avatar id>,
"type": "user",
"last_seen_on": "2016-10-27 19:58:22",
"name": "Podio TESTER"
},
"sort_by": "created_on",
"items": 0,
"created_on": "2016-10-27 19:58:26",
"private": true,
"filters": [],
"filter_id": 31011898,
"groupings": {},
"type": "private",
"view_id": 31011898,
"grouping": {}
}
Here's a PHP version, authentication performed prior to request:
// UPDATE VIEW
$authorization = 'Authorization: Bearer '.$auth_token;
$json = json_encode(array(
"sort_desc" => false,
"filters" => array(
999994986 => array(
"to" => 10000,
"from" => 0.01
),
999999204 => array(
"to" => $end,
"from" => $first
)
)
));
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.podio.com/view/99999909",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS =>$json,
CURLOPT_HTTPHEADER => array(
$authorization,
"Content-Type: application/json"
),
));
$response = curl_exec($curl);
curl_close($curl);