PayPal
Mobilne przyszłe płatności (aplikacja End to End)
Szukaj…
Uwagi
Ten przykład pokazuje praktyczny przykład tworzenia przyszłej płatności PayPal z urządzenia z systemem Android za pomocą serwera Node.
Android Krok 1: Układ, inicjalizacja i obsługa odpowiedzi serwera
Pełny przykładowy kod dla tej aplikacji (serwer Android + węzeł) jest dostępny w repozytorium Github dla deweloperów PayPal .
Pierwszym etapem tworzenia części aplikacji dla Androida jest skonfigurowanie podstawowego układu i obsługa odpowiedzi, które wrócą z serwera, który skonfigurujemy w Węzle.
Zacznij od utworzenia nowego obiektu PayPalConfiguration do przechowywania informacji o aplikacji.
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"));
Następnie dodajemy prosty przycisk do onCreate(...) aby działał jako nasza inicjacja płatności. Ma to na celu uruchomienie akcji i powinno zostać umieszczone jako proces inicjujący w celu utworzenia przyszłej płatności dla użytkownika (np. Kiedy zgadzają się na subskrypcję).
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.paypal_button);
}
W res > layout > activity_main.xml dodajemy definicję przycisku z powiązaną z nim akcją, po kliknięciu wywołuje beginFuturePayment(...) , którą zdefiniujemy za chwilę.
<Button android:id="@+id/paypal_button"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/paypal_button"
android:onClick="beginFuturePayment" />
W obszarze res > values > strings.xml dodajemy odwołanie do ciągu dla przycisku.
<string name="paypal_button">Process Future Payment</string>
Teraz dodajemy moduł obsługi przycisków, aby zainicjować połączenie i rozpocząć przyszły proces płatności, gdy użytkownik kliknie przycisk. To, co robimy tutaj, polega na uruchomieniu usługi płatności za pomocą obiektu konfiguracyjnego, który ustawiliśmy na początku tego przykładu.
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);
}
Po zainicjowaniu połączenia w celu dokonania przyszłej płatności otrzymamy pewne informacje, które należy wysłać na nasz serwer. authCode te informacje z prawidłowego przyszłego żądania płatności ( authCode i metadataId ), a następnie wykonujemy żądanie asynchroniczne do serwera, aby dokończyć przyszłą płatność (szczegółowo w kroku 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");
}
}
Na koniec definiujemy naszą onDestroy() .
@Override
public void onDestroy(){
stopService(new Intent(this, PayPalService.class));
super.onDestroy();
}
Android Krok 2: żądanie serwera asynchronicznego
Pełny przykładowy kod dla tej aplikacji (serwer Android + węzeł) jest dostępny w repozytorium Github dla deweloperów PayPal .
W tym momencie kliknięto przycisk Przyszłe płatności PayPal, mamy kod uwierzytelniający i identyfikator metadanych z zestawu SDK PayPal i musimy przekazać je naszemu serwerowi, aby dokończyć przyszły proces płatności.
W poniższym procesie w tle wykonujemy kilka rzeczy:
-
/fpstoreidentyfikator URI, który dla naszego serwera tohttp://10.0.2.2:3000/fpstore, który uderza w punkt końcowy/fpstorenaszego serwera działającego na localhost. - Następnie konfigurowany jest obiekt JSON, który zostanie wysłany, zawierający kod autoryzacji i identyfikator metadanych.
- Połączenie zostanie nawiązane. W przypadku pomyślnego żądania (zakres 200/201) możemy oczekiwać odpowiedzi z serwera. Czytamy tę odpowiedź, a następnie ją zwracamy.
- Na koniec mamy
onPostExecute(...)skonfigurowaną do obsługi zwracanego ciągu serwera. W przypadku tego przykładu jest on po prostu zalogowany.
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 Krok 3: Węzeł serwera, aby uzyskać dostęp do tokena i płatności procesowej
Pełny przykładowy kod dla tej aplikacji (serwer Android + węzeł) jest dostępny w repozytorium Github dla deweloperów PayPal .
Od kroku 2 wysłano żądanie asynchroniczne do naszego serwera w /fpstore końcowym /fpstore , przekazując kod /fpstore i identyfikator metadanych. Teraz musimy je wymienić na token, aby zrealizować żądanie i przetworzyć przyszłą płatność.
Najpierw konfigurujemy nasze zmienne konfiguracyjne i obiekt.
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());
Teraz skonfigurowaliśmy trasę ekspresową, która będzie nasłuchiwać żądań POST wysyłanych do punktu końcowego /fpstore z naszego kodu Androida.
Robimy wiele rzeczy na tej trasie:
- Przechwytujemy kod uwierzytelniający i identyfikator metadanych z ciała POST.
- Następnie przesyłamy żądanie do
generateToken(), przechodząc przez obiekt kodu. Jeśli się powiedzie, otrzymamy token, którego można użyć do utworzenia płatności. - Następnie tworzone są obiekty konfiguracyjne dla przyszłej płatności, która ma być wykonana, i
payment.create(...)jest żądanie dopayment.create(...), przekazując przyszłe obiekty konfiguracyjne płatności i płatności. To tworzy przyszłą płatność.
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));
}
});
}
});
});
Na koniec tworzymy serwer do nasłuchiwania na porcie 3000.
//create server
http.createServer(app).listen(3000, function () {
console.log('Server started: Listening on port 3000');
});