tuurbo / spreedly Goto Github PK
View Code? Open in Web Editor NEWSpreedly.com PHP API
License: MIT License
Spreedly.com PHP API
License: MIT License
You should not be doing times on the amount. Because the currency cannot always be split into 100.
For example YPN (japanese) will not be multiplied with 100.
I am thinking use tuurbo/spreedly in laravel 5.1 but i don't know if is compatible, is it?
For the new general credit method, the error is this:
Amount should be specified as an integer value corresponding to the number of cents. Example: $42.34 is 4234 cents.
I assume that the other methods are doing this for me, but not general_credit
From https://docs.spreedly.com/guides/3dsecure/
<transaction>
<on_test_gateway type="boolean">false</on_test_gateway>
<created_at type="dateTime">2015-01-08T21:04:22Z</created_at>
<updated_at type="dateTime">2015-01-08T21:04:22Z</updated_at>
<succeeded type="boolean">false</succeeded>
<state>pending</state>
<token>AYNT7hwbLm2eAN2LYnCxanVlHVv</token>
<transaction_type>Purchase</transaction_type>
<order_id nil="true"/>
<ip nil="true"/>
<description nil="true"/>
<email nil="true"/>
<merchant_name_descriptor nil="true"/>
<merchant_location_descriptor nil="true"/>
<gateway_specific_fields nil="true"/>
<gateway_specific_response_fields nil="true"/>
<gateway_transaction_id nil="true"/>
<amount type="integer">100</amount>
<currency_code>USD</currency_code>
<retain_on_success type="boolean">false</retain_on_success>
<payment_method_added type="boolean">false</payment_method_added>
<message key="messages.transaction_pending">Pending</message>
<gateway_token>8XJtbE1p4NTZ6fFqwwn0GrkjEmW</gateway_token>
<api_urls>
<callback_conversations>https://core.spreedly.com/v1/callbacks/XjCHPJad2pDbIKKq2fOJezXmxiM/conversations.xml</callback_conversations>
</api_urls>
<payment_method>
<token>XTpo2jo5q3mXi9uXsrDNyzeRkK9</token>
<created_at type="dateTime">2015-01-08T16:04:22-05:00</created_at>
<updated_at type="dateTime">2015-01-08T16:04:22-05:00</updated_at>
<email nil="true"/>
<data nil="true"/>
<storage_state>cached</storage_state>
<test type="boolean">true</test>
<last_four_digits>3886</last_four_digits>
<first_six_digits>455676</first_six_digits>
<card_type>visa</card_type>
<first_name>Bob</first_name>
<last_name>Smith</last_name>
<month type="integer">2</month>
<year type="integer">2020</year>
<address1 nil="true"/>
<address2 nil="true"/>
<city nil="true"/>
<state nil="true"/>
<zip nil="true"/>
<country nil="true"/>
<phone_number nil="true"/>
<full_name>Bob Smith</full_name>
<eligible_for_card_updater type="boolean">true</eligible_for_card_updater>
<shipping_address1 nil="true"/>
<shipping_address2 nil="true"/>
<shipping_city nil="true"/>
<shipping_state nil="true"/>
<shipping_zip nil="true"/>
<shipping_country nil="true"/>
<shipping_phone_number nil="true"/>
<payment_method_type>credit_card</payment_method_type>
<errors>
</errors>
<verification_value>XXX</verification_value>
<number>XXXX-XXXX-XXXX-3886</number>
</payment_method>
<callback_url>http://127.0.0.1:3044</callback_url>
<redirect_url>http://example.com/handle_redirect</redirect_url>
<checkout_url nil="true"/>
<checkout_form>
<![CDATA[
<form action="https://core.spreedly.com/test/8XJtbE1p4NTZ6fFqwwn0GrkjEmW/auth/AYNT7hwbLm2eAN2LYnCxanVlHVv" method="POST">
<div>
<input name="PaReq" value="" type="hidden"/>
<input name="MD" value="" type="hidden"/>
<input name="TermUrl" value="https://core.spreedly.com/transaction/AYNT7hwbLm2eAN2LYnCxanVlHVv/redirect" type="hidden"/>
<input name="Complete" value="Authorize Transaction" type="submit"/>
</div>
</form>
]]>
</checkout_form>
<setup_response>
<success type="boolean">true</success>
<message>Checked enrollment status</message>
<error_code></error_code>
<checkout_url nil="true"/>
<created_at type="dateTime">2015-01-08T21:04:22Z</created_at>
<updated_at type="dateTime">2015-01-08T21:04:22Z</updated_at>
</setup_response>
</transaction>
$client = new \Tuurbo\Spreedly\Client(new \GuzzleHttp\Client, []);
checkout_form
is a CDATA field and $client->response('checkout_form')
returns empty string.
This is because default Guzzle config doesn't set LIBXML_NOCDATA
flag for SimpleXMLElement
. See: http://php.net/manual/en/libxml.constants.php#constant.libxml-nocdata
Fix:
--- vendor/tuurbo/spreedly/src/Client.php Tue Oct 20 17:53:03 2015
+++ vendor/tuurbo/spreedly/src/Client.php Tue Oct 20 18:05:33 2015
@@ -82,7 +82,13 @@
{
if ($response->getHeader('Content-Type') === 'application/xml; charset=utf-8')
{
- $response = $response->xml();
+ // We overwrite Guzzle libxml options
+ // as by default it doesn't show CDATA fields
+ $xmlConfig = [
+ 'libxml_options' => (LIBXML_NONET | LIBXML_NOCDATA),
+ ];
+
+ $response = $response->xml($xmlConfig);
}
else
{
I am trying to create a Spreedly client using:
// Retrieve transaction from POST data
$xmlText = file_get_contents('php://input', 'r');
$xml = new SimpleXMLElement($xmlText, LIBXML_NONET | LIBXML_NOCDATA);
// We expect only one transaction
$transactionXml = $xml->children()[0];
$client = new \Tuurbo\Spreedly\Client(new \GuzzleHttp\Client, []);
$client->setResponse($transactionXml);
Problem I have is that when response is set that way, status
of the response does not get set on the client. Therefore the result of $client->success()
and $client->fails()
is always false.
I think it would be better if the code that sets the status:
if (isset($this->response['error']) || (isset($this->response['succeeded']) && $this->response['succeeded'] == 'false'))
{
$this->status = 'error';
return $this;
}
$this->status = 'success';
was inside setResponse method.
--- vendor/tuurbo/spreedly/src/Client.php Tue Oct 20 17:53:03 2015
+++ vendor/tuurbo/spreedly/src/Client.php Tue Oct 20 17:53:06 2015
@@ -58,15 +58,6 @@
$this->setResponse($response);
- if (isset($this->response['error']) || (isset($this->response['succeeded']) && $this->response['succeeded'] == 'false'))
- {
- $this->status = 'error';
-
- return $this;
- }
-
- $this->status = 'success';
-
return $this;
}
@@ -93,6 +84,15 @@
$response = json_decode(json_encode((array) $response), true);
$this->response = $this->cleanArray($response);
+
+ if (isset($this->response['error']) || (isset($this->response['succeeded']) && $this->response['succeeded'] == 'false'))
+ {
+ $this->status = 'error';
+
+ return $this;
+ }
+
+ $this->status = 'success';
}
/**
Does this library support a general credit? One that follows this: https://docs.spreedly.com/reference/api/v1/gateways/general-credit/
Thank you,
Daniel
Is this method missing for a reason?
According to Spreedly guide:
Note: Worldpay uses postMessages to notify when authentication needs to progress to the next step. We pass these parameters in event.context.
{"MessageType": "profile.completed", "SessionId": "d3197c02-6f63-4ab2-801c-83633d097e32","Status": true)
These parameters should be included in the complete call using the key context.
{context: {"MessageType": "profile.completed", "SessionId": "d3197c02-6f63-4ab2-801c-83633d097e32", "Status": true}}
These parameters will only be sent during trigger-completion events
Would it be possible to allow to pass an array $data in the complete() call (it could be empty by default)?
/**
* Can be used to Completes a 3DS 2 transaction in the device fingerprint stage
* See docs for more information.
*
* <code>
* // Completes a 3DS 2 transaction in the device fingerprint stage.
* Spreedly::transaction($transactionToken)->complete($data);
* </code>
*
*
* @return mixed
*
* @throws Exceptions\MissingTransactionTokenException
*/
public function complete(array $data = [])
{
if (!$this->transactionToken) {
throw new Exceptions\MissingTransactionTokenException();
}
return $this->client->post('v1/transactions/'.$this->transactionToken.'/complete.json', $data);
}
What is the max allowed timeout in the setup?
According to Spreedly we need to set it to 64 seconds to be safe. https://docs.spreedly.com/reference/api/old/timeouts/
Is it possible in the current code to hit this resource?
https://docs.spreedly.com/reference/api/v1/#show
GET /v1/gateways/<gateway_token>.<format>
Should I PR?
We need the ability to change the base URL with a config. This is because we need to route our spreedly calls through another service first then do some mappings and let that other service then forward to spreedly.
If I submit a PR which would allow overriding the Base spreedly URL (but still defaulting to the correct url) would that be something you would approve or is this something you'd rather me maintain in a separate fork?
In the Client::request() method you are checking for certain error codes and throwing exceptions when they occur, but if it's not one you check for, you just set $this->status = 'error'
so that user's of the library must check for this variable every single time we make a request.
Code: https://github.com/tuurbo/spreedly/blob/master/src/Client.php#L82
Are you opposed to always throwing an exception on line 82? If you are, would you be opposed to adding a configuration variable we could set to throw exceptions (that's disabled by default)? I can write the code if you like.
We've seen Spreedly APIs returning HTTP 504
and other error response codes that aren't currently throwing an exception so our code just keeps chugging along.
I'm excited to use this library. However when doing composer update
I get this error:
Your requirements could not be resolved to an installable set of packages.
Problem 1
- tuurbo/spreedly 0.9.2 requires guzzlehttp/guzzle ~4.0 -> no matching package found.
- tuurbo/spreedly 0.9.1 requires guzzlehttp/guzzle ~4.0 -> no matching package found.
- tuurbo/spreedly 0.9.0 requires guzzlehttp/guzzle ~4.0 -> no matching package found.
- Installation request for tuurbo/spreedly ~0.9 -> satisfiable by tuurbo/spreedly[0.9.0, 0.9.1, 0.9.2].
Before finding this library I was hitting spreedly with guzzle directly, and using Guzzle 5.2. Is there a way I can overwrite your requirement of an old version of Guzzle? Or, is that even the problem.
A new endpoint transactions/{token}/complete
has been added to be able to complete a
3DS 2 transaction (https://docs.spreedly.com/reference/api/v1/transactions/). The SDK cannot reach that endpoint right now so a new method like the one below should be added to src/Transaction.php
/**
* Can be used to Completes a 3DS 2 transaction in the device fingerprint stage
* See docs for more information.
*
* <code>
* // Completes a 3DS 2 transaction in the device fingerprint stage.
* Spreedly::transaction($transactionToken)->complete();
* </code>
*
*
* @return mixed
*
* @throws Exceptions\MissingTransactionTokenException
*/
public function complete()
{
if (!$this->transactionToken) {
throw new Exceptions\MissingTransactionTokenException();
}
return $this->client->post('v1/transactions/'.$this->transactionToken.'/complete.json');
}
In Client model.
For instance, if $this->response['payment_method'] is not set, then paymentToken() throws an exception, but response('payment_method.token') correctly returns null.
Is this expected behaviour? Should paymentToken not be wrapping a call to response(), rather than accessing the attribute directly?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.