I am trying to integrate stripe into my android application with the server code set up in Backendless as a Custom API Service. After charging the card, with a successful call back method, I am not able to see that in my payments list on my stripe dashboard. Not sure where the problem is. Any suggestions will be appreciated.Below is what I have so far:
ChargeItem://Charge Class
package com.mbaas.service;
public class ChargeItem {
public String token;
public int price;
public String description;
}
ChargeService //Backendless Service
import com.stripe.Stripe;
import com.stripe.exception.StripeException;
import com.stripe.model.Charge;
import java.util.HashMap;
import java.util.Map;
public class ChargeService implements IBackendlessService
{
public boolean makeCharge(ChargeItem charges){
Stripe.apiKey = "my stripe secret key";
// Get the credit card details submitted by the form
String token = charges.token;
double price = charges.price;
String desc = charges.description;
String userId = charges.userId;
String orderId = charges.orderId;
// Create a charge: this will charge the user's card
try {
Map<String, Object> chargeParams = new HashMap<String, Object>();
chargeParams.put("orderId",orderId);
chargeParams.put("userId",userId);
chargeParams.put("amount", price); // Amount in cents
chargeParams.put("currency", "usd");
chargeParams.put("source", token);
chargeParams.put("description", desc);
#SuppressWarnings("unused")
Charge charge = Charge.create(chargeParams);
}
catch (StripeException e) {
// The card has been declined
return false;
}
return true;
}
}
//My stripe token call back method
private void convertCardToToken(Card card, final Orders order){
Stripe stripe = new Stripe(getApplicationContext(), CustomApplication.PUBLISHABLE_KEY);
stripe.createToken(
card,
new TokenCallback() {
public void onSuccess(Token token) {
// Send token to your server
ChargeItem chargeItem = new ChargeItem();
chargeItem.setToken(token.getId());
chargeItem.setOrderId(order.getObjectId());
chargeItem.setPrice(order.getOrder_price());
chargeItem.setUserName(order.getOwnerId());
chargeItem.setDescription("Delivery Fee");
ChargeService.initApplication();
ChargeService chargeService = ChargeService.getInstance();
chargeService.makeChargeAsync(chargeItem, new AsyncCallback<Boolean>() {
#Override
public void handleResponse(Boolean response) {
Toast.makeText(getApplicationContext(),
"Payment Successful",
Toast.LENGTH_LONG
).show();
}
#Override
public void handleFault(BackendlessFault fault) {
Toast.makeText(getApplicationContext(), fault.getMessage(),
Toast.LENGTH_LONG
).show();
}
});
}
public void onError(Exception error) {
// Show localized error message
Toast.makeText(CheckoutActivity.this,
error.getLocalizedMessage(),
Toast.LENGTH_LONG
).show();
}
}
);
}
I'm not familiar with Backendless so I cannot provide much help here, but there a few issues with your code:
price is a double. To avoid rounding errors, all amounts in Stripe's API are in cents (or more generally, in the smallest unit for the currency you're using), so price should be an int.
userId and orderId are not valid parameters when creating a charge. You likely want to pass these variables as metadata values.
To help you debug further, you should also check your logs in your Stripe account's dashboard at https://dashboard.stripe.com/test/logs?method=not_get. You should see requests to POST /v1/tokens (sent by your Android app) and requests to POST /v1/charges (sent by Backendless).
Related
I made another post to explain better, ok? :)
This video shows exactly what I mean:
The video is: https://www.youtube.com/watch?v=DCg00fe-_xs
Firebase normally stores data. After the 6th second of the video, trying to enter new data, the data stays about a second in Firebase, but automatically then it disappears.
I try to input the data into Firebase two more times in this video, but the data always automatically disappears afterwards.
You can see that the other datas that are stored in Firebase does NOT disappear. But the data of this code is automatically disappearing for some reason as shown in the video. Please what can I do to fix it?
Code:
button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String raça = spinner_raca.getSelectedItem().toString();
final String regiaoDoEstado = spinner_regiaoDoEstado.getSelectedItem().toString();
final String estado = spinner_estado.getSelectedItem().toString();
Intent receiverIntent = getIntent();
Bundle bundleRecebedor = receiverIntent.getExtras();
String nomecompleto = bundleRecebedor.getString("nomecompleto");
String email = bundleRecebedor.getString("email");
String doencasPreExistentes = bundleRecebedor.getString("doencasPreExistentes");
String dataDeNascimento = bundleRecebedor.getString("dataDeNascimento");
String genero = bundleRecebedor.getString("genero");
String identificadorEmHash = bundleRecebedor.getString("identificadorEmHash");
String telefone = receiverIntent.getStringExtra("telefone");
reference = FirebaseDatabase.getInstance().getReference().child("Usuarios").child(identificadorEmHash);
Toast.makeText(getApplicationContext(), identificadorEmHash, Toast.LENGTH_LONG).show();
if(identificadorEmHash.equals(null)) {
Toast.makeText(getApplicationContext(), "The identifier does not exist", Toast.LENGTH_LONG).show();
} else {
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
reference = FirebaseDatabase.getInstance().getReference().child("Usuarios").child(identificadorEmHash);
if (!dataSnapshot.exists()) {
Toast.makeText(getApplicationContext(), "The identifier does not exist", Toast.LENGTH_LONG).show();
} else {
HashMap<String, String> sendDataToDataBase = new HashMap<>();
sendDataToDataBase.put("Nome Completo", nomecompleto);
sendDataToDataBase.put("E-mail", email);
sendDataToDataBase.put("Identificador em Hash", identificadorEmHash);
sendDataToDataBase.put("Telefone", telefone);
sendDataToDataBase.put("Doenças Pré Existentes", doencasPreExistentes);
sendDataToDataBase.put("Data de Nascimento", dataDeNascimento);
sendDataToDataBase.put("Gênero", genero);
// When I am going to send the following data to Firebase, the problem of the video happens.
sendDataToDataBase.put("Região do Estado em que mora", regiaoDoEstado);
sendDataToDataBase.put("Raça", raça);
sendDataToDataBase.put("Estado do Brasil em que mora", estado);
try {
raiz.child(identificadorEmHash).setValue(sendDataToDataBase);
} catch (Exception e) {
e.getMessage();
}
}
}
});
}
}
});
Please, can someone help me to fix this bug?
Firebase doesn't automatically delete data, so if you see the data show up in the console it was written there by a client/API call, and allowed by your security rules. If the data subsequently gets updates or removed again, there is another client/API call that does so.
I recommend checking for realtime listeners in your code, that may be responding to your first write by updating (and accidentally reverting) that operation. It is also quite common to have a server-side script that is doing this.
Update: one thing you can try is to use updateChildren instead of setValue in all places such as this one:
raiz.child(identificadorEmHash).updateChildren(sendDataToDataBase)
I'm implement Razorpay with PaymentResultWithDataListener. Actually i need order_id and signature so i use PaymentResultWithDataListener not used PaymentResultListener because there are no option to get order_id and signature. And I have follow these links
https://docs.razorpay.com/v1/page/orders#verifying-the-signature
https://razorpay.com/mobile/
https://github.com/razorpay/razorpay-android-sample-app
But not getting any solution.
Menifest File
<meta-data
android:name="com.razorpay.ApiKey"
android:value="rzp_test_PLbERPkkqGZkOF" />
build.gradle
api 'com.razorpay:checkout:1.5.4'
I got an error
{"code":"BAD_REQUEST_ERROR","description":"ay_order_id is not a valid id"}
I am trying with this code
public class CheckoutActivity extends AppCompatActivity implements View.OnClickListener, PaymentResultWithDataListener {
private static final String TAG = CheckoutActivity.class.getSimpleName();
Button mCheckOutView;
String OrderId = "";
String signature = "";
String order_id = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_payment_method);
Checkout.preload(getApplicationContext());
mCheckOutView = findViewById(R.id.check_out);
mCheckOutView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v == mCheckOutView) {
startPayment();
}
}
public void startPayment() {
/*
You need to pass current activity in order to let Razorpay create CheckoutActivity
*/
final Activity activity = this;
final Checkout co = new Checkout();
try {
JSONObject options = new JSONObject();
options.put("name","Test");
options.put("description", getString(R.string.app_name));
options.put("key", getString(R.string.api_key));
options.put("order_id","razorpay_order_id");
options.put("signature","razorpay_signature");
options.put("currency", "INR");
options.put("amount", 100);
JSONObject preFill = new JSONObject();
preFill.put("email", "test#gmail.com");
preFill.put("contact", "9999999999");
options.put("prefill", preFill);
JSONObject notesData=new JSONObject();
notesData.put("Order Id","order123");
notesData.put("address","Test Address");
options.put("notes", notesData);
JSONObject theme=new JSONObject();
theme.put("color","#738598");
theme.put("emi_mode",true);
options.put("theme", theme);
co.open(activity, options);
} catch (Exception e) {
Toast.makeText(activity, "Error in payment: " + e.getMessage(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
#Override
public void onPaymentSuccess(String s, PaymentData paymentData) {
String paymentId = paymentData.getPaymentId();
String signature = paymentData.getSignature(); // got null
String orderId = paymentData.getOrderId(); // got null
}
#Override
public void onPaymentError(int i, String s, PaymentData paymentData) {
Log.e(TAG,s); //error {"code":"BAD_REQUEST_ERROR","description":"ay_order_id is not a valid id"}
}
}
If i remove these 2 lines then this error not comes.
options.put("order_id","razorpay_order_id");
options.put("signature","razorpay_signature");
But paymentData.getSignature() and paymentData.getOrderId() is null.
Any help will be appreciated.
options.put("order_id","**razorpay_order_id**");
you need to generate this order_id from razorpay Order_ID API, only after this order_id which comes as a response from the API you would be able to process smoothly. After getting this Order_id from API, send it in above code in value (in place of razorpay_order_id)
options.put("signature","razorpay_signature");
This is not required in request. This will be generated at your server and will be used when a response is received in PaymentResultWithDataListener function. Read Signature generation method in official Documentation here : https://razorpay.com/docs/payment-gateway/android-integration/standard/
According to the official docs, by the time you start the checkout, you get the order_id when the merchant's backend starts an order with the RazorPay backend.
See the diagram here`.
As for the signature, according with the docs that's not something you put but something that comes from server responses and which you have to validate on your end. Check this
I need a working example for a custom API for Microsoft Azure App Service.
I could not get any useful or working information/examples for that, or they just show each time different approaches which are outdated?!?!
For now I have a working table controller which gets information from database and returns it back to my Android client. Now I need to define a custom API Controller to get a string back. In the examples they are all sending an object to the service in order to get an object back. I do not want to send anything to the API, just retrieve some information back from a GET Request.
Regards
// EDIT - Added / edited client / server code to Post a String.
You can use the following code to do a GET request on the auto generated API controller Visual Studio creates (ValuesController).
private void getStringFromAzure() throws MalformedURLException {
// Create the MobileService Client object and set your backend URL
String yourURL = "https://yourApp.azurewebsites.net/";
MobileServiceClient mClient = new MobileServiceClient(yourURL, this);
// Your query pointing to yourURL/api/values
ListenableFuture<JsonElement> query = mClient.invokeApi("values", null, GetMethod, null);
// Callback method
Futures.addCallback(query, new FutureCallback<JsonElement>() {
#Override
public void onSuccess(JsonElement jsonElement) {
// You are expecting a String you can just output the result.
final String result = jsonElement.toString();
// Since you are on a async task, you need to show the result on the UI thread
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(mContext, result, Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onFailure(Throwable throwable) {
Log.d(TAG, "onFailure: " + throwable.getMessage());
}
});
}
public void sendString(final String someString) throws MalformedURLException {
// Your query pointing to /api/values/{String}
ListenableFuture<JsonElement> query = mClient.invokeApi("values/" + someString, null, PostMethod, null);
// Callback method
Futures.addCallback(query, new FutureCallback<JsonElement>() {
#Override
public void onSuccess(JsonElement jsonElement) {
// You are expecting a String you can just output the result.
final String result = jsonElement.toString();
}
#Override
public void onFailure(Throwable throwable) { }
});
}
The backend API: (ValuesController)
{
// Use the MobileAppController attribute for each ApiController you want to use
// from your mobile clients
[MobileAppController]
public class ValuesController : ApiController
{
// GET api/values
public string Get()
{
return "Hello World!";
}
// POST api/values/inputString
public string Post(string inputString)
{
return inputString;
}
}
}
You can also send parameters along in the following way:
List<Pair<String, String>> parameters = new ArrayList<>();
parameters.add(new Pair<>("name", "John"));
parameters.add(new Pair<>("password", "fourwordsalluppercase"));
ListenableFuture<JsonElement> query = client.invokeApi("yourAPI", PostMethod, parameters);
Or as json in the body:
JsonObject body = new JsonObject();
body.addProperty("currentPassword", currentPassword);
body.addProperty("password", password);
body.addProperty("confirmPassword", confirmPassword);
ListenableFuture<JsonElement> query = mClient.invokeApi("yourAPI", body, PostMethod, null);
Based on my understanding, I think there are two parts in your question which include as below. And I think you can separately refer to two sections to get the answers and write your own example.
How to define a custom API on Azure Mobile App to retrieve data from database? Please refer to the section Custom APIs to know how to do with Azure Mobile App backend.
How to call a custom API from Android App? Please refer to the section How to: Call a custom API to know how to do with Android SDK.
The situation is as following:
I send a login request using the method showLoginUI and then, after selecting a provider (Twitter, g+, etc.) the app goes to the onError callback of my GSLoginUIListener with the error "Account pending registration". Until that point, everything is fine. The problem is when I try to create another GSRequest with the method "accounts.setAccountInfo" like in the following code:
GSRequest setAccountInfoRequest = new GSRequest(getString(R.string.gigya_api_key),"accounts.setAccountInfo");
As parameter, I believe I have to add the regToken but where can I get it? In the iOS SDK, there is an Error object (that you get from the GSResponse that allows you to get it like this:
token = error.userInfo["regToken"]
But there is nothing like that on the Android SDK, from the GSResponse I just can get the error code, error message and error details. So, in short, how can I get the regToken that I need for my request? In the documentation does not go into the details of the actual implementation and I have not seen any examples.
Unlike the iOS and .NET SDKs, the Android SDK does not have a publicly expose or documented GSRequest class, so invoking a request the way you are doing it is not advisable.
Instead, you should use GSAPI.sendRequest with a GSResponseListener. The GSResponseListener will have a response object with the method getData which can be invoked to get a dictionary object of all the parameters returned from the request.
An example of how this can be done is provided in our Gigya CS Android demo hosted on GitHub and can be examined in the file SessionInfoFragment.java#121-191.
public void refreshView() {
GSAPI gigya = GSAPI.getInstance();
final TextView statusText = (TextView) rootView.findViewById(R.id.status_value);
final TextView nameText = (TextView) rootView.findViewById(R.id.name_value);
final TextView emailText = (TextView) rootView.findViewById(R.id.email_value);
final ImageView avatarView = (ImageView) rootView.findViewById(R.id.avatar);
if (gigya.getSession() != null){
if (gigya.getSession().isValid()) {
MainActivity parent = (MainActivity) getActivity();
GSObject user = parent.getUser();
// Retrieve the user if it's not set. (Reloaded app with active session)
if (user == null) {
GSResponseListener resListener = new GSResponseListener() {
#Override
public void onGSResponse(String method, GSResponse response, Object context) {
try {
if (response.getErrorCode()==0) { // SUCCESS! response status = OK
MainActivity parent = (MainActivity) getActivity();
Log.w("Gigya-Android-Demos", "Successfully set user");
parent.setUser(response.getData());
setLoggedIn(statusText, nameText, emailText, avatarView, response.getData());
} else { // Error
Log.w("Gigya-Android-Demos", "GSResponse: 'getAccountInfo' returned an error");
Log.w("Gigya-Android-Demos", response.getErrorMessage());
}
} catch (Exception ex) { ex.printStackTrace(); }
}
};
GSAPI.getInstance()
.sendRequest("accounts.getAccountInfo", null, resListener, null );
} else {
// Grab the user data
setLoggedIn(statusText, nameText, emailText, avatarView, user);
}
} else {
setLoggedOut(statusText, nameText, emailText, avatarView);
}
} else {
setLoggedOut(statusText, nameText, emailText, avatarView);
}
}
public void setLoggedOut(TextView status, TextView name, TextView email, ImageView avatar) {
status.setText(getString(R.string.logged_out));
name.setText(getString(R.string.null_value));
email.setText(getString(R.string.null_value));
setUnknownAvatar(avatar);
}
public void setLoggedIn(TextView status, TextView name, TextView emailView, ImageView avatar, GSObject user) {
status.setText(getString(R.string.logged_in));
try {
GSObject profile = user.getObject("profile");
String first = profile.getString("firstName");
String last = profile.getString("lastName");
String email = profile.getString("email");
if (profile.containsKey("photoURL")) {
setAvatar(avatar,profile.getString("photoURL"));
} else {
setUnknownAvatar(avatar);
}
name.setText(first + " " + last);
emailView.setText(email);
} catch (Exception ex) {
Log.w("Gigya-Android-Demos", "Something went horribly wrong with the user!");
ex.printStackTrace();
}
}
You should notice the use of getData() and GSObject classes throughout the example provided. Using this method of making a request, you should be able to examine the response data including the regToken.
I am trying to develop a Facebook application for Android. I am unable to integrate the "Add Comment" feature to photos in Facebook Albums. Using the Graph API, I can show the previously made comments on a photo. However, I just can't add new comments to a photo.
Can somebody provide me some helpful advice?
here is simple example on doing that..
// post comment to single photo
Bundle parameters = new Bundle();
String target = "";
target = "<PHOTO_ID>/comments";
parameters.putString("message", "post Comment testing");
mAsyncRunner.request(target, parameters, "POST", new FacebookRequestListener(target+" (post comment)"));
and here is a simple example for the listener (you can get this from examples of facebook-android-sdk too)
public class FacebookRequestListener extends BaseRequestListener {
String caller = "default";
public FacebookRequestListener() {
}
public FacebookRequestListener(String caller) {
this.caller = caller;
}
public void onComplete(final String response) {
try {
Log.d(TAG, "FacebookRequestListener|"+caller+":" + response);
} catch (Exception e) {
Log.w(TAG, "Error:"+e.getMessage());
}
}
}