Skip to content

Commit 49ef13e

Browse files
author
epriestley
committedMay 21, 2013
Add WePay as a one-time payment provider
Summary: Ref T2787. I //think// we could also use WePay as a recurring payment provider, but this is somewhat messy (OAuth + requires account) -- basically it's "add a WePay account" instead of "add a credit card". The WePay checkout workflow is a bit upsell-y but basically reasonable. I like that their API just has a `request($method, $params)` method instead of 30,000 lines of methods for each request type. I did hit one bug; I'll send a pull for that. Test Plan: Got as far as the charge callback in testing; the rest isn't implemented for any provider yet. Reviewers: btrahan, vrana, chad Reviewed By: btrahan CC: aran Maniphest Tasks: T2787 Differential Revision: https://secure.phabricator.com/D5982
1 parent fab9a13 commit 49ef13e

15 files changed

+905
-0
lines changed
 

‎externals/wepay/README.md

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
WePay PHP SDK
2+
=============
3+
4+
WePay's API allows you to easily add payments into your application.
5+
6+
For full documentation, see [WePay's developer documentation](https://www.wepay.com/developer)
7+
8+
Usage
9+
-----
10+
11+
In addition to the samples below, we have included a very basic demo application in the `demoapp` directory. See its README file for additional information.
12+
13+
### Configuration ###
14+
15+
For all requests, you must initialize the SDK with your Client ID and Client Secret, into either Staging or Production mode. All API calls made against WePay's staging environment mirror production in functionality, but do not actually move money. This allows you to develop your application and test the checkout experience from the perspective of your users without spending any money on payments. Our [full documentation](https://www.wepay.com/developer) contains additional information on test account numbers you can use in addition to "magic" amounts you can use to trigger payment failures and reversals (helpful for testing IPNs).
16+
17+
**Note:** Staging and Production are two completely independent environments and share NO data with each other. This means that in order to use staging, you must register at [stage.wepay.com](https://stage.wepay.com/developer) and get a set of API keys for your Staging application, and must do the same on Production when you are ready to go live. API keys and access tokens granted on stage *can not* be used on Production, and vice-versa.
18+
19+
<?php
20+
require './wepay.php';
21+
WePay::useProduction('YOUR CLIENT ID', 'YOUR CLIENT SECRET'); // To initialize staging, use WePay::useStaging('ID','SECRET'); instead.
22+
23+
### Authentication ###
24+
25+
To obtain an access token for your user, you must redirect the user to WePay for authentication. WePay uses OAuth2 for authorization, which is detailed [in our documentation](https://www.wepay.com/developer/reference/oauth2). To generate the URI to which you must redirect your user, the SDK contains `WePay::getAuthorizationUri($scope, $redirect_uri)`. `$scope` should be an array of scope strings detailed in the documentation. To request full access (most useful for testing, since users may be weary of granting permission to your application if it wants to do too much), you pay pass in `WePay::getAllScopes()`. `$redirect_uri` must be a fully qualified URI where we will send the user after permission is granted (or not granted), and the domain must match your application settings.
26+
27+
If the user grants permission, he or she will be redirected to your `$redirect_uri` with `code=XXXX` appended to the query string. If permission is not granted, we will instead put `error=XXXX` in the query string. If `code` is present, the following will exchange it for an access token. Note that codes are only valid for several minutes, so you should do this immediately after the user is redirected back to your website or application.
28+
29+
<?php
30+
if (!empty($_GET['error'])) {
31+
// user did not grant permissions
32+
}
33+
elseif (empty($_GET['code'])) {
34+
// set $scope and $redirect_uri before doing this
35+
// this will send the user to WePay to authenticate
36+
$uri = WePay::getAuthorizationUri($scope, $redirect_uri);
37+
header("Location: $uri");
38+
exit;
39+
}
40+
else {
41+
$info = WePay::getToken($_GET['code'], $redirect_uri);
42+
if ($info) {
43+
// YOUR ACCESS TOKEN IS HERE
44+
$access_token = $info->access_token;
45+
}
46+
else {
47+
// Unable to obtain access token
48+
}
49+
}
50+
51+
Full details on the access token response are [here](https://www.wepay.com/developer/reference/oauth2#token).
52+
53+
**Note:** If you only need access for yourself (e.g., for a personal storefront), the application settings page automatically creates an access token for you. Simply copy and paste it into your code rather than manually going through the authentication flow.
54+
55+
### Making API Calls ###
56+
57+
With the `$access_token` from above, get a new SDK object:
58+
59+
<?php
60+
$wepay = new WePay($access_token);
61+
62+
Then you can make a simple API call. This will list the user's accounts available to your application:
63+
64+
// (continued from above)
65+
try {
66+
$accounts = $wepay->request('account/find');
67+
foreach ($accounts as $account) {
68+
echo "<a href=\"$account->account_uri\">$account->name</a>: $account->description <br />";
69+
}
70+
}
71+
catch (WePayException $e) {
72+
// Something went wrong - normally you would log
73+
// this and give your user a more informative message
74+
echo $e->getMessage();
75+
}
76+
77+
And that's it! For more detail on what API calls are available, their parameters and responses, and what permissions they require, please see [our documentation](https://www.wepay.com/developer/reference). For some more detailed examples, look in the `demoapp` directory and check the README. Dropping the entire directory in a web-accessible location and adding your API keys should allow you to be up and running in just a few seconds.
78+
79+
### SSL Certificate ###
80+
81+
If making an API call causes the following problem:
82+
83+
Uncaught exception 'Exception' with message 'cURL error while making API call to WePay: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed'
84+
85+
You can read the solution here: https://support.wepay.com/entries/21095813-problem-with-ssl-certificate-verification

‎externals/wepay/demoapp/README

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
After registering your application at wepay.com (or stage.wepay.com), you
2+
need to make two updates to this application:
3+
4+
1 - set your client_id and client_secret in _shared.php
5+
2 - set the redirect_uri in login.php
6+
7+
That should be enough to start making API calls against WePay's API. While
8+
this is by no means a production-ready example, it should provide you a
9+
couple ideas on how to get running.
10+
11+
It also defaults to requesting all possible scope fields in the
12+
authentication request. We suggest limiting the request to the minimum
13+
your application requires, which will maximize the chance the user
14+
grants permissions to your application. You can customize this in
15+
login.php.
16+
17+
If you have any questions, please contact the API team: api@wepay.com
18+
19+
- WePay

‎externals/wepay/demoapp/_shared.php

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?php
2+
require '../wepay.php';
3+
Wepay::useStaging('YOUR CLIENT ID', 'YOUR CLIENT SECRET');
4+
session_start();
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
require './_shared.php';
3+
?>
4+
<h1>WePay Demo App: Account List</h1>
5+
<a href="index.php">Back</a>
6+
<br />
7+
8+
<?php
9+
try {
10+
$wepay = new WePay($_SESSION['wepay_access_token']);
11+
$accounts = $wepay->request('account/find');
12+
foreach ($accounts as $account) {
13+
echo "<a href=\"$account->account_uri\">$account->name</a>: $account->description <br />";
14+
}
15+
}
16+
catch (WePayException $e) {
17+
// Something went wrong - normally you would log
18+
// this and give your user a more informative message
19+
echo $e->getMessage();
20+
}

‎externals/wepay/demoapp/index.php

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
require './_shared.php';
3+
?>
4+
5+
<h1>WePay Demo App</h1>
6+
<?php if (empty($_SESSION['wepay_access_token'])): ?>
7+
8+
<a href="login.php">Log in with WePay</a>
9+
10+
<?php else: ?>
11+
12+
<a href="user.php">User info</a>
13+
<br />
14+
<a href="openaccount.php">Open new account</a>
15+
<br />
16+
<a href="accountlist.php">Account list</a>
17+
<br />
18+
<a href="logout.php">Log out</a>
19+
20+
<?php endif; ?>

‎externals/wepay/demoapp/login.php

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
require './_shared.php';
3+
4+
// ** YOU MUST CHANGE THIS FOR THE SAMPLE APP TO WORK **
5+
$redirect_uri = 'http://YOUR SERVER NAME/login.php';
6+
$scope = WePay::getAllScopes();
7+
8+
// If we are already logged in, send the user home
9+
if (!empty($_SESSION['wepay_access_token'])) {
10+
header('Location: index.php');
11+
exit;
12+
}
13+
14+
// If the authentication dance returned an error, catch it to avoid a
15+
// redirect loop. This usually indicates some sort of application issue,
16+
// like a domain mismatch on your redirect_uri
17+
if (!empty($_GET['error'])) {
18+
echo 'Error during user authentication: ';
19+
echo htmlentities($_GET['error_description']);
20+
exit;
21+
}
22+
23+
// If we don't have a code from being redirected back here,
24+
// send the user to WePay to grant permissions.
25+
if (empty($_GET['code'])) {
26+
$uri = WePay::getAuthorizationUri($scope, $redirect_uri);
27+
header("Location: $uri");
28+
}
29+
else {
30+
$info = WePay::getToken($_GET['code'], $redirect_uri);
31+
if ($info) {
32+
// Normally you'd integrate this into your existing auth system
33+
$_SESSION['wepay_access_token'] = $info->access_token;
34+
// If desired, you can also store $info->user_id somewhere
35+
header('Location: index.php');
36+
}
37+
else {
38+
// Unable to obtain access token
39+
echo 'Unable to obtain access token from WePay.';
40+
}
41+
}

‎externals/wepay/demoapp/logout.php

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
session_start();
3+
$_SESSION = array();
4+
session_destroy();
5+
header('Location: index.php');
6+
exit;
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
require './_shared.php';
3+
?>
4+
<h1>WePay Demo App: Open Account</h1>
5+
<a href="index.php">Back</a>
6+
<br />
7+
8+
<?php
9+
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
10+
if (isset($_POST['account_name']) && isset($_POST['account_description'])) {
11+
// WePay sanitizes its own data, but displaying raw POST data on your own site is a XSS security hole.
12+
$name = htmlentities($_POST['account_name']);
13+
$desc = htmlentities($_POST['account_description']);
14+
try {
15+
$wepay = new WePay($_SESSION['wepay_access_token']);
16+
$account = $wepay->request('account/create', array(
17+
'name' => $name,
18+
'description' => $desc,
19+
));
20+
echo "Created account $name for '$desc'! View on WePay at <a href=\"$account->account_uri\">$account->account_uri</a>. See all of your accounts <a href=\"accountlist.php\">here</a>.";
21+
}
22+
catch (WePayException $e) {
23+
// Something went wrong - normally you would log
24+
// this and give your user a more informative message
25+
echo $e->getMessage();
26+
}
27+
}
28+
else {
29+
echo 'Account name and description are both required.';
30+
}
31+
}
32+
?>
33+
34+
<form method="post">
35+
<fieldset>
36+
<legend>Account Info</legend>
37+
38+
<label for="account_name">Account Name:</label><br />
39+
<input type="text" id="account_name" name="account_name" placeholder="Ski Trip Savings"/>
40+
41+
<br /><br />
42+
43+
<label for="account_description">Account Description: </label><br />
44+
<textarea name="account_description" rows="10" cols="40" placeholder="Saving up some dough for our ski trip!"></textarea>
45+
46+
<br /><br />
47+
48+
<input type="submit" value="Open account" />
49+
</fieldset>
50+
</form>

‎externals/wepay/demoapp/user.php

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
require './_shared.php';
3+
?>
4+
<h1>WePay Demo App: User Info</h1>
5+
<a href="index.php">Back</a>
6+
<br />
7+
8+
<?php
9+
try {
10+
$wepay = new WePay($_SESSION['wepay_access_token']);
11+
$user = $wepay->request('user');
12+
echo '<dl>';
13+
foreach ($user as $key => $value) {
14+
echo "<dt>$key</dt><dd>$value</dd>";
15+
}
16+
echo '</dl>';
17+
}
18+
catch (WePayException $e) {
19+
// Something went wrong - normally you would log
20+
// this and give your user a more informative message
21+
echo $e->getMessage();
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
/**
3+
* This PHP script helps you do the iframe checkout
4+
*
5+
*/
6+
7+
8+
/**
9+
* Put your API credentials here:
10+
* Get these from your API app details screen
11+
* https://stage.wepay.com/app
12+
*/
13+
$client_id = "PUT YOUR CLIENT_ID HERE";
14+
$client_secret = "PUT YOUR CLIENT_SECRET HERE";
15+
$access_token = "PUT YOUR ACCESS TOKEN HERE";
16+
$account_id = "PUT YOUR ACCOUNT_ID HERE"; // you can find your account ID via list_accounts.php which users the /account/find call
17+
18+
/**
19+
* Initialize the WePay SDK object
20+
*/
21+
require '../wepay.php';
22+
Wepay::useStaging($client_id, $client_secret);
23+
$wepay = new WePay($access_token);
24+
25+
/**
26+
* Make the API request to get the checkout_uri
27+
*
28+
*/
29+
try {
30+
$checkout = $wepay->request('/checkout/create', array(
31+
'account_id' => $account_id, // ID of the account that you want the money to go to
32+
'amount' => 100, // dollar amount you want to charge the user
33+
'short_description' => "this is a test payment", // a short description of what the payment is for
34+
'type' => "GOODS", // the type of the payment - choose from GOODS SERVICE DONATION or PERSONAL
35+
'mode' => "iframe", // put iframe here if you want the checkout to be in an iframe, regular if you want the user to be sent to WePay
36+
)
37+
);
38+
} catch (WePayException $e) { // if the API call returns an error, get the error message for display later
39+
$error = $e->getMessage();
40+
}
41+
42+
?>
43+
44+
<html>
45+
<head>
46+
</head>
47+
48+
<body>
49+
50+
<h1>Checkout:</h1>
51+
52+
<p>The user will checkout here:</p>
53+
54+
<?php if (isset($error)): ?>
55+
<h2 style="color:red">ERROR: <?php echo $error ?></h2>
56+
<?php else: ?>
57+
<div id="checkout_div"></div>
58+
59+
<script type="text/javascript" src="https://stage.wepay.com/js/iframe.wepay.js">
60+
</script>
61+
62+
<script type="text/javascript">
63+
WePay.iframe_checkout("checkout_div", "<?php echo $checkout->checkout_uri ?>");
64+
</script>
65+
<?php endif; ?>
66+
67+
</body>
68+
69+
</html>

0 commit comments

Comments
 (0)
Failed to load comments.