PayPal
Mobila framtida betalningar (app från slutet till slut)
Sök…
Anmärkningar
Detta exempel visar ett praktiskt exempel på slutet till slut på att skapa en framtida PayPal-betalning från en Android-enhet med en Node-server.
Android Steg 1: Layout, initiering och hantering av serverrespons
Den fullständiga provkoden för den här applikationen (Android + Node-server) är tillgänglig i PayPal Developer Github-arkivet .
Det första steget i att skapa Android-delen av vår applikation är att skapa en grundläggande layout och hantera svar som kommer tillbaka från servern som vi ställer in i Node.
Börja med att skapa ett nytt PayPalConfiguration-objekt för att hysa din applikationsinformation.
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"));
Därefter lägger vi till en enkel knapp till onCreate(...) att fungera som vår betalningsinitiering. Detta är helt enkelt för att utlösa åtgärden och bör placeras som initieringsprocessen för att skapa en framtida betalning för en användare (t.ex. när de går med på ett prenumeration).
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.paypal_button);
}
Under res > layout > activity_main.xml lägger vi till definitionen för knappen med tillhörande åtgärd, när man beginFuturePayment(...) den beginFuturePayment(...) , som vi definierar på en minut.
<Button android:id="@+id/paypal_button"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/paypal_button"
android:onClick="beginFuturePayment" />
Under res > values > strings.xml vi sedan till en strängreferens för knappen.
<string name="paypal_button">Process Future Payment</string>
Nu lägger vi till knapphanteraren för att initiera samtalet för att starta den framtida betalningsprocessen när användaren klickar på knappen. Det vi gör här är att starta betalningstjänsten med det konfigurationsobjekt som vi satt upp högst upp i detta exempel.
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);
}
När det samtalet för att göra en framtida betalning inleds kommer vi att få viss information som måste skickas till vår server. Vi extraherar den här informationen från den giltiga framtida betalningsbegäran ( authCode och metadataId ) och kör sedan async-begäran till servern för att slutföra den framtida betalningen (beskrivs i steg 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");
}
}
Slutligen definierar vi vår onDestroy() .
@Override
public void onDestroy(){
stopService(new Intent(this, PayPalService.class));
super.onDestroy();
}
Android Steg 2: Async Server Request
Den fullständiga provkoden för den här applikationen (Android + Node-server) är tillgänglig i PayPal Developer Github-arkivet .
Vid denna tidpunkt har knappen för framtida betalningar för PayPal klickats, vi har en autorisationskod och metadata-ID från PayPal SDK, och vi måste vidarebefordra dem till vår server för att slutföra den framtida betalningsprocessen.
I bakgrundsprocessen nedan gör vi några saker:
- Vi skapade URI för att vår server ska vara
http://10.0.2.2:3000/fpstore, vilket träffar/fpstoreslutpunkt för vår server som körs på localhost. - JSON-objektet som kommer att skickas in skapas sedan, som innehåller autorisationskoden och metadata-ID.
- Anslutningen görs sedan. Vid en framgångsrik begäran (200/201-intervall) kan vi förvänta oss ett svar tillbaka från servern. Vi läser det svaret och returnerar sedan det.
- Slutligen har vi en
onPostExecute(...)-metod inställd för att hantera den returnerade serversträngen. I det här exemplet loggas det helt enkelt.
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 Steg 3: Nodserver för att få åtkomsttoken och bearbeta betalning
Den fullständiga provkoden för den här applikationen (Android + Node-server) är tillgänglig i PayPal Developer Github-arkivet .
Från steg 2 har en async-begäran gjorts till vår server vid /fpstore slutpunkten och passerar ID-koden och metadata-ID. Vi måste nu byta ut dem mot ett symbol för att slutföra begäran och behandla den framtida betalningen.
Först ställer vi in våra konfigurationsvariabler och objekt.
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());
Nu skapar vi en Express-rutt som lyssnar på POST-förfrågningar som skickas till /fpstore slutpunkt från vår Android-kod.
Vi gör ett antal saker på den här vägen:
- Vi fångar autorisationskoden och metadata-ID från POST-organet.
- Vi gör sedan en begäran om att
generateToken()och passerar kodobjektet. Om det lyckas får vi ett symbol som kan användas för att skapa betalningen. - Därefter skapas konfigurationsobjekten för den framtida betalningen som ska göras, och en begäran till
payment.create(...)görs och passerar framtida betalnings- och betalningskonfigurationsobjekt. Detta skapar den framtida betalningen.
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));
}
});
}
});
});
Slutligen skapar vi servern för att lyssna på port 3000.
//create server
http.createServer(app).listen(3000, function () {
console.log('Server started: Listening on port 3000');
});