PayPal
Pagos futuros móviles (aplicación de extremo a extremo)
Buscar..
Observaciones
Este ejemplo muestra un ejemplo práctico de principio a fin de crear un pago futuro de PayPal desde un dispositivo Android, utilizando un servidor Node.
Paso 1 de Android: diseño, inicialización y manejo de la respuesta del servidor
El código de muestra completo para esta aplicación (servidor Android + Node) está disponible en el repositorio de Github para desarrolladores de PayPal .
La primera etapa de crear la parte de Android de nuestra aplicación es configurar un diseño básico y manejar las respuestas que provienen del servidor que configuraremos en Node.
Comience por crear un nuevo objeto PayPalConfiguration para alojar la información de su aplicación.
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"));
A continuación, agregamos un botón simple a onCreate(...) para que actúe como nuestra iniciación de pago. Esto es simplemente para desencadenar la acción, y debe colocarse como el proceso de inicio para crear un pago futuro para un usuario (por ejemplo, cuando acuerdan una suscripción).
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.paypal_button);
}
En res > layout > activity_main.xml agregamos la definición del botón con su acción asociada, cuando se hace clic, se llama beginFuturePayment(...) , que definiremos en un minuto.
<Button android:id="@+id/paypal_button"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/paypal_button"
android:onClick="beginFuturePayment" />
Bajo res > values > strings.xml , luego agregamos una referencia de cadena para el botón.
<string name="paypal_button">Process Future Payment</string>
Ahora agregamos el controlador de botones, para iniciar la llamada para comenzar el proceso de pago futuro cuando el usuario haga clic en el botón. Lo que estamos haciendo aquí es iniciar el servicio de pago con el objeto de configuración que configuramos en la parte superior de este ejemplo.
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);
}
Cuando se inicie la llamada para realizar un pago en el futuro, se nos proporcionará cierta información que deberá enviarse a nuestro servidor. authCode esta información de la solicitud de pago futuro válida ( authCode y metadataId ), luego ejecutamos la solicitud asíncrona al servidor para completar el pago futuro (detallado en el paso 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");
}
}
Por último, definimos nuestro onDestroy() .
@Override
public void onDestroy(){
stopService(new Intent(this, PayPalService.class));
super.onDestroy();
}
Android Paso 2: Async Server Request
El código de muestra completo para esta aplicación (servidor Android + Node) está disponible en el repositorio de Github para desarrolladores de PayPal .
En este punto, se hizo clic en el botón de pagos futuros de PayPal, tenemos un código de autenticación y un ID de metadatos del SDK de PayPal, y debemos pasarlos a nuestro servidor para completar el proceso de pago futuro.
En el proceso de fondo a continuación, estamos haciendo algunas cosas:
- Configuramos el URI para que nuestro servidor sea
http://10.0.2.2:3000/fpstore, que está llegando al/fpstorefinal/fpstorede nuestro servidor que se ejecuta en localhost. - Luego se configura el objeto JSON que se enviará a través, que contiene el código de autenticación y el ID de metadatos.
- Luego se realiza la conexión. En el caso de una solicitud exitosa (rango 200/201) podemos esperar una respuesta del servidor. Leemos esa respuesta y luego la devolvemos.
- Por último, tenemos un
onPostExecute(...)configurado para manejar esa cadena de servidor devuelta. En el caso de este ejemplo, simplemente se registra.
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);
}
}
Paso 3 de Android: Servidor de nodo para obtener el token de acceso y procesar el pago
El código de muestra completo para esta aplicación (servidor Android + Node) está disponible en el repositorio de Github para desarrolladores de PayPal .
Desde el paso 2, se realizó una solicitud asíncrona a nuestro servidor en el /fpstore final /fpstore , pasando el código de autenticación y el ID de metadatos. Ahora necesitamos cambiarlos por un token para completar la solicitud y procesar el pago futuro.
Primero configuramos nuestras variables de configuración y objeto.
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());
Ahora configuramos una ruta Express que escuchará las solicitudes POST enviadas al punto final /fpstore desde nuestro código de Android.
Estamos haciendo una serie de cosas en esta ruta:
- Capturamos el código de autenticación y el ID de metadatos del cuerpo POST.
- Luego realizamos una solicitud para
generateToken(), pasando por el objeto de código. Si tiene éxito, obtenemos un token que se puede utilizar para crear el pago. - A continuación, los objetos de configuración se crean para el pago futuro que se realizará, y se realiza una solicitud a
payment.create(...), que pasa a través de los pagos futuros y los objetos de configuración de pago. Esto crea el pago futuro.
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));
}
});
}
});
});
Por último, creamos el servidor para escuchar en el puerto 3000.
//create server
http.createServer(app).listen(3000, function () {
console.log('Server started: Listening on port 3000');
});