PayPal
Мобильные будущие платежи (от конца до конца)
Поиск…
замечания
В этом примере показан практический пример конца будущего платежа PayPal с Android-устройства с использованием сервера Node.
Android Шаг 1: Макет, инициализация и обработка ответов сервера
Полный образец кода для этого приложения (сервер Android + Node) доступен в репозитории PayPal Developer Github .
Первым этапом создания части приложения Android является настройка базового макета и обработка ответов, возвращаемых с сервера, который мы установим в узле.
Начните с создания нового объекта PayPalConfiguration для размещения информации о вашем приложении.
private static PayPalConfiguration config = new PayPalConfiguration()
.environment(PayPalConfiguration.ENVIRONMENT_SANDBOX)
.clientId("YOUR APPLICATION CLIENT ID")
.merchantName("My Store")
.merchantPrivacyPolicyUri(Uri.parse("https://www.example.com/privacy"))
.merchantUserAgreementUri(Uri.parse("https://www.example.com/legal"));
Затем добавим простую кнопку onCreate(...) чтобы действовать как начало платежа. Это просто инициирует действие и должно быть помещено в качестве процесса инициирования для создания будущего платежа для пользователя (например, когда они согласны с подпиской).
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.paypal_button);
}
В разделе res > layout > activity_main.xml мы добавим определение для кнопки со связанным с ней действием, при нажатии на нее называется beginFuturePayment(...) , который мы определим через минуту.
<Button android:id="@+id/paypal_button"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/paypal_button"
android:onClick="beginFuturePayment" />
В разделе res > values > strings.xml мы добавим строчную ссылку для кнопки.
<string name="paypal_button">Process Future Payment</string>
Теперь мы добавляем обработчик кнопки, чтобы инициировать вызов, чтобы начать процесс будущих платежей, когда пользователь нажимает кнопку. Что мы делаем здесь, это запуск платежного сервиса с помощью объекта конфигурации, который мы установили в верхней части этого примера.
public void beginFuturePayment(View view){
Intent serviceConfig = new Intent(this, PayPalService.class);
serviceConfig.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
startService(serviceConfig);
Intent intent = new Intent(this, PayPalFuturePaymentActivity.class);
intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
startActivityForResult(intent, 0);
}
Когда будет инициирован вызов для будущего платежа, нам будет предоставлена некоторая информация, которая должна быть отправлена на наш сервер. Мы извлекаем эту информацию из действительного будущего платежного запроса ( authCode и metadataId ), затем выполняем запрос асинхронного запроса на сервер для завершения будущей оплаты (подробно описанный в шаге 2).
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data){
if (resultCode == Activity.RESULT_OK){
PayPalAuthorization auth = data.getParcelableExtra(PayPalFuturePaymentActivity.EXTRA_RESULT_AUTHORIZATION);
if (auth != null){
try{
//prepare params to be sent to server
String authCode = auth.getAuthorizationCode();
String metadataId = PayPalConfiguration.getClientMetadataId(this);
String [] params = {authCode, metadataId};
//process async server request for token + payment
ServerRequest req = new ServerRequest();
req.execute(params);
} catch (JSONException e) {
Log.e("FPSample", "JSON Exception: ", e);
}
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Log.i("FPSample", "User canceled.");
} else if (resultCode == PayPalFuturePaymentActivity.RESULT_EXTRAS_INVALID) {
Log.i("FPSample", "Invalid configuration");
}
}
Наконец, мы определяем наш onDestroy() .
@Override
public void onDestroy(){
stopService(new Intent(this, PayPalService.class));
super.onDestroy();
}
Android Шаг 2: Запрос сервера Async
Полный образец кода для этого приложения (сервер Android + Node) доступен в репозитории PayPal Developer Github .
На этом этапе нажата кнопка будущих платежей PayPal, у нас есть код аутентификации и идентификатор метаданных из SDK PayPal, и нам нужно передать их на наш сервер, чтобы завершить процесс будущих платежей.
В фоновом процессе ниже мы делаем несколько вещей:
- Мы настроили URI, чтобы для нашего сервера был
http://10.0.2.2:3000/fpstore, который попадает в/fpstoreточку/fpstoreнашего сервера, работающего на localhost. - Затем будет создан объект JSON, который будет отправлен через него, который содержит код аутентификации и идентификатор метаданных.
- Затем соединение будет выполнено. В случае успешного запроса (диапазон 200/201) мы можем ожидать ответа с сервера. Мы читаем этот ответ, а затем возвращаем его.
- Наконец, у нас есть
onPostExecute(...)настроенный для обработки возвращенной строки сервера. В случае этого примера он просто регистрируется.
public class ServerRequest extends AsyncTask<String, Void, String> {
protected String doInBackground(String[] params){
HttpURLConnection connection = null;
try{
//set connection to connect to /fpstore on localhost
URL u = new URL("http://10.0.2.2:3000/fpstore");
connection = (HttpURLConnection) u.openConnection();
connection.setRequestMethod("POST");
//set configuration details
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
connection.setAllowUserInteraction(false);
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
//set server post data needed for obtaining access token
String json = "{\"code\": \"" + params[0] + "\", \"metadataId\": \"" + params[1] + "\"}";
Log.i("JSON string", json);
//set content length and config details
connection.setRequestProperty("Content-length", json.getBytes().length + "");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
//send json as request body
OutputStream outputStream = connection.getOutputStream();
outputStream.write(json.getBytes("UTF-8"));
outputStream.close();
//connect to server
connection.connect();
//look for 200/201 status code for received data from server
int status = connection.getResponseCode();
switch (status){
case 200:
case 201:
//read in results sent from the server
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null){
sb.append(line + "\n");
}
bufferedReader.close();
//return received string
return sb.toString();
}
} catch (MalformedURLException ex) {
Log.e("HTTP Client Error", ex.toString());
} catch (IOException ex) {
Log.e("HTTP Client Error", ex.toString());
} catch (Exception ex) {
Log.e("HTTP Client Error", ex.toString());
} finally {
if (connection != null) {
try{
connection.disconnect();
} catch (Exception ex) {
Log.e("HTTP Client Error", ex.toString());
}
}
}
return null;
}
protected void onPostExecute(String message){
//log values sent from the server - processed payment
Log.i("HTTP Client", "Received Return: " + message);
}
}
Android Шаг 3: Сервер узла для получения доступа к токенам и процессинговым платежам
Полный образец кода для этого приложения (сервер Android + Node) доступен в репозитории PayPal Developer Github .
Начиная с шага 2, асинхронный запрос был /fpstore нашему серверу в /fpstore точке /fpstore , передавая код аутентификации и идентификатор метаданных. Теперь нам нужно обменять их на токен, чтобы выполнить запрос и обработать будущий платеж.
Сначала мы настраиваем наши переменные конфигурации и объект.
var bodyParser = require('body-parser'),
http = require('http'),
paypal = require('paypal-rest-sdk'),
app = require('express')();
var client_id = 'YOUR APPLICATION CLIENT ID';
var secret = 'YOUR APPLICATION SECRET';
paypal.configure({
'mode': 'sandbox',
'client_id': client_id,
'client_secret': secret
});
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json());
Теперь мы настроили экспресс-маршрут, который будет прослушивать запросы POST, отправленные в /fpstore точку /fpstore из нашего кода Android.
На этом пути мы делаем несколько вещей:
- Мы фиксируем код аутентификации и идентификатор метаданных из тела POST.
- Затем мы делаем запрос на
generateToken(), проходя через объект кода. В случае успеха мы получаем токен, который можно использовать для создания платежа. - Затем создаются объекты конфигурации для будущей оплаты, которая должна быть сделана, и делается запрос на
payment.create(...), проходящий через будущие объекты конфигурации оплаты и оплаты. Это создает будущий платеж.
app.post('/fpstore', function(req, res){
var code = {'authorization_code': req.body.code};
var metadata_id = req.body.metadataId;
//generate token from provided code
paypal.generateToken(code, function (error, refresh_token) {
if (error) {
console.log(error);
console.log(error.response);
} else {
//create future payments config
var fp_config = {'client_metadata_id': metadata_id, 'refresh_token': refresh_token};
//payment details
var payment_config = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"transactions": [{
"amount": {
"currency": "USD",
"total": "3.50"
},
"description": "Mesozoic era monster toy"
}]
};
//process future payment
paypal.payment.create(payment_config, fp_config, function (error, payment) {
if (error) {
console.log(error.response);
throw error;
} else {
console.log("Create Payment Response");
console.log(payment);
//send payment object back to mobile
res.send(JSON.stringify(payment));
}
});
}
});
});
Наконец, мы создаем сервер для прослушивания на порту 3000.
//create server
http.createServer(app).listen(3000, function () {
console.log('Server started: Listening on port 3000');
});