PayPal
Mobile Future Payments (Ende-zu-Ende-App)
Suche…
Bemerkungen
Dieses Beispiel zeigt ein praktisches End-to-End-Beispiel für das Erstellen einer zukünftigen PayPal-Zahlung von einem Android-Gerät unter Verwendung eines Knotenservers.
Android Schritt 1: Layout, Initialisierung und Handhabung der Serverantwort
Den vollständigen Beispielcode für diese Anwendung (Android + Node-Server) finden Sie im PayPal Developer Github-Repository .
Der erste Schritt beim Erstellen des Android-Teils unserer Anwendung besteht darin, ein grundlegendes Layout festzulegen und Antworten zu verarbeiten, die von dem Server stammen, den wir in Node einrichten.
Erstellen Sie zunächst ein neues PayPalConfiguration-Objekt, um Ihre Anwendungsinformationen unterzubringen.
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"));
Als Nächstes fügen wir eine einfache Schaltfläche für onCreate(...) , die als Zahlungsanweisung dient. Dies dient einfach dazu, die Aktion auszulösen, und sollte als Initiierungsprozess für das Erstellen einer zukünftigen Zahlung für einen Benutzer (z. B. wenn sie ein Abonnement vereinbaren) platziert werden.
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.paypal_button);
}
Unter res > layout > activity_main.xml fügen wir die Definition für die Schaltfläche mit der zugehörigen Aktion hinzu. Wenn Sie darauf beginFuturePayment(...) , wird der beginFuturePayment(...) , den wir in einer Minute definieren.
<Button android:id="@+id/paypal_button"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/paypal_button"
android:onClick="beginFuturePayment" />
Unter res > values > strings.xml fügen wir dann eine Zeichenfolge für die Schaltfläche hinzu.
<string name="paypal_button">Process Future Payment</string>
Jetzt fügen wir den Button-Handler hinzu, um den Anruf einzuleiten, um den zukünftigen Zahlungsvorgang zu starten, wenn der Benutzer auf die Schaltfläche klickt. Wir starten hier den Zahlungsservice mit dem Konfigurationsobjekt, das wir oben in diesem Beispiel eingerichtet haben.
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);
}
Wenn dieser Anruf für eine zukünftige Zahlung initiiert wird, erhalten wir einige Informationen, die an unseren Server gesendet werden müssen. Wir extrahieren diese Informationen aus der gültigen zukünftigen Zahlungsanforderung ( authCode und metadataId ) und führen dann die async-Anforderung an den Server aus, um die zukünftige Zahlung abzuschließen (detailliert in Schritt 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");
}
}
Zuletzt definieren wir unser onDestroy() .
@Override
public void onDestroy(){
stopService(new Intent(this, PayPalService.class));
super.onDestroy();
}
Android Schritt 2: Async Server Request
Den vollständigen Beispielcode für diese Anwendung (Android + Node-Server) finden Sie im PayPal Developer Github-Repository .
An diesem Punkt wurde die Schaltfläche "PayPal für zukünftige Zahlungen" angeklickt, wir haben einen Authentifizierungscode und eine Metadaten-ID aus dem PayPal-SDK. Diese Informationen müssen an unseren Server weitergeleitet werden, um den zukünftigen Zahlungsvorgang abzuschließen.
Im Hintergrundprozess unten machen wir ein paar Dinge:
- Wir haben den URI so eingerichtet, dass er für unseren Server
http://10.0.2.2:3000/fpstoreist/fpstoretrifft auf den/fpstoreEndpunkt unseres Servers, der auf localhost ausgeführt wird. - Das JSON-Objekt, durch das gesendet wird, wird dann eingerichtet, das den Authentifizierungscode und die Metadaten-ID enthält.
- Die Verbindung wird dann hergestellt. Im Falle einer erfolgreichen Anfrage (Bereich 200/201) können wir eine Antwort vom Server erwarten. Wir lesen diese Antwort und geben sie zurück.
- Schließlich haben wir eine
onPostExecute(...)-Methode eingerichtet, um diese zurückgegebene Serverzeichenfolge zu verarbeiten. In diesem Beispiel wird es einfach protokolliert.
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 Schritt 3: Knotenserver, um Zugriffstoken zu erhalten und Zahlung zu verarbeiten
Den vollständigen Beispielcode für diese Anwendung (Android + Node-Server) finden Sie im PayPal Developer Github-Repository .
Ab Schritt 2 wurde eine asynchrone Anforderung an unseren Server am Endpunkt /fpstore , wobei der Authentifizierungscode und die Metadaten-ID übergeben wurden. Wir müssen diese jetzt gegen ein Token eintauschen, um die Anfrage abzuschließen und die zukünftige Zahlung zu bearbeiten.
Zuerst richten wir unsere Konfigurationsvariablen und Objekte ein.
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());
Jetzt richten wir eine Express-Route ein, die POST-Anforderungen /fpstore von unserem Android-Code an den Endpunkt /fpstore gesendet werden.
Wir machen eine Reihe von Dingen auf dieser Route:
- Wir erfassen den Authentifizierungscode und die Metadaten-ID aus dem POST-Body.
- Wir stellen dann eine Anforderung an
generateToken()und übergeben das Code-Objekt. Bei Erfolg erhalten wir ein Token, mit dem die Zahlung erstellt werden kann. - Als nächstes werden die Konfigurationsobjekte für die zukünftige Zahlung erstellt, die durchgeführt werden soll, und eine Anforderung an
payment.create(...)wirdpayment.create(...), wobei die zukünftigen Zahlungs- und Zahlungskonfigurationsobjekte übergeben werden. Dies schafft die zukünftige Zahlung.
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));
}
});
}
});
});
Als letztes erstellen wir den Server, um Port 3000 zu überwachen.
//create server
http.createServer(app).listen(3000, function () {
console.log('Server started: Listening on port 3000');
});