I am Integrating Paytm PGSDK_V2.0 in my android app. I have read all documentation on Github. I have understand everything.but the problem is in its earlier SDK where we can simply generate checksum using Paytm Merchant object Like:
PaytmMerchant merchant=new PaytmMerchant("Checksum generation url","Checksum verification url");
and put this in Service Like this
Service.initialize(Order,merchant,null);
But in new SDK it change to
Service.initialize(Order,null);
So please help me how to generate checksum in new SDK
Paytm has change process to increase the security. now in PGSDK_V2.0 first you have to generate through calling the api Checksum Generation on your server side
Like this:
#Override
protected String doInBackground(String... params) {
url ="http://xxx.co.in/generateChecksum.php";
JSONParser jsonParser = new JSONParser(MainActivity.this);
param="ORDER_ID=" + orderId+
"&MID="+YourMID+
"&CUST_ID="+custId+
"&CHANNEL_ID=WAP&INDUSTRY_TYPE_ID=Retail110&WEBSITE=xxxwap&TXN_AMOUNT="+billAmt+"&CALLBACK_URL=http://xxx.co.in/verifyChecksum.php";
JSONObject jsonObject = jsonParser.makeHttpRequest(url,"POST",param);
Log.e("CheckSum result >>",jsonObject.toString());
if(jsonObject != null){
Log.d("CheckSum result >>",jsonObject.toString());
try {
CHECKSUMHASH=jsonObject.has("CHECKSUMHASH")?jsonObject.getString("CHECKSUMHASH"):"";
Log.e("CheckSum result >>",CHECKSUMHASH);
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
now after getting CHECKSUM string in your onPostExecute initialize paytm Service object and do further process Like This:
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progressDialog.hide();
Service = PaytmPGService.getProductionService();
/*PaytmMerchant constructor takes two parameters
1) Checksum generation url
2) Checksum verification url
Merchant should replace the below values with his values*/
//below parameter map is required to construct PaytmOrder object, Merchant should replace below map values with his own values
Map<String, String> paramMap = new HashMap<String, String>();
//these are mandatory parameters
paramMap.put("ORDER_ID", orderId);
//MID provided by paytm
paramMap.put("MID", yourMID);
paramMap.put("CUST_ID", custId);
paramMap.put("CHANNEL_ID", "WAP");
paramMap.put("INDUSTRY_TYPE_ID", "Retail");
paramMap.put("WEBSITE", "xxxwap");
paramMap.put("TXN_AMOUNT",billAmt);
//
paramMap.put("CALLBACK_URL" ,"http://xxx.co.in/verifyChecksum.php");
paramMap.put("CHECKSUMHASH" ,CHECKSUMHASH);
PaytmOrder Order = new PaytmOrder(paramMap);
Service.initialize(Order,null);
Service.startPaymentTransaction(ReviewBooking.this, true, true, new PaytmPaymentTransactionCallback() {
#Override
public void someUIErrorOccurred(String inErrorMessage) {
// Some UI Error Occurred in Payment Gateway Activity.
// // This may be due to initialization of views in
// Payment Gateway Activity or may be due to //
// initialization of webview. // Error Message details
// the error occurred.
}
#Override
public void onTransactionResponse(Bundle inResponse) {
Log.d("LOG", "Payment Transaction : " + inResponse);
String response=inResponse.getString("RESPMSG");
if (response.equals("Txn Successful."))
{
new ConfirmMerchent().execute();
}else
{
Toast.makeText(getApplicationContext(),response,Toast.LENGTH_SHORT).show();
}
Toast.makeText(getApplicationContext(), "Payment Transaction response "+inResponse.toString(), Toast.LENGTH_LONG).show();
}
#Override
public void networkNotAvailable() {
// If network is not
// available, then this
// method gets called.
}
#Override
public void clientAuthenticationFailed(String inErrorMessage) {
// This method gets called if client authentication
// failed. // Failure may be due to following reasons //
// 1. Server error or downtime. // 2. Server unable to
// generate checksum or checksum response is not in
// proper format. // 3. Server failed to authenticate
// that client. That is value of payt_STATUS is 2. //
// Error Message describes the reason for failure.
}
#Override
public void onErrorLoadingWebPage(int iniErrorCode,
String inErrorMessage, String inFailingUrl) {
}
// had to be added: NOTE
#Override
public void onBackPressedCancelTransaction() {
// TODO Auto-generated method stub
}
#Override
public void onTransactionCancel(String inErrorMessage, Bundle inResponse) {
Log.d("LOG", "Payment Transaction Failed " + inErrorMessage);
Toast.makeText(getBaseContext(), "Payment Transaction Failed ", Toast.LENGTH_LONG).show();
}
});
}
JsonParser Class
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
HttpURLConnection urlConnection = null;
// variable to hold context
private Context context;
// constructor
public JSONParser(Context context){
this.context=context;
}
public JSONObject makeHttpRequest(String url,String method,String params) {
// boolean isReachable =Config.isURLReachable(context);
// Making HTTP request
try {
String retSrc="";
char current = '0';
URL url1 = new URL(url);
// check for request method
HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection();
if (method == "POST") {
// request method is POST
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setFixedLengthStreamingMode(params.getBytes().length);
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
PrintWriter out = new PrintWriter(urlConnection.getOutputStream());
out.print(params);
out.close();
}
InputStream in = urlConnection.getInputStream();
InputStreamReader isw = new InputStreamReader(in);
byte[] bytes = new byte[10000];
StringBuilder x = new StringBuilder();
int numRead = 0;
while ((numRead = in.read(bytes)) >= 0) {
x.append(new String(bytes, 0, numRead));
}
retSrc=x.toString();
jObj = new JSONObject(retSrc);
} catch (Exception e) {
e.printStackTrace();
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(context, "Connectivity issue. Please try again later.", Toast.LENGTH_LONG).show();
}
});
return null;
}finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return jObj;
}
}
and parameter values should be same both time.
Generating Checksum is quite easy.
Just get the Paytm App Checksum Kit from Github.
Extract the downloaded kit and put it in your server. If you are using a local server using xampp then the path would be c:/xampp/htdocs/paytm. I would recommend renaming the folder name to paytm or a small name.
Inside the kit there is a folder named lib. Inside this folder you will find a file named config_paytm.php, Open this file and put your Paytm Merchant Key here.
Now you can use the file generateChecksum.php to generate checksum.
Remember you need to pass every parameter that you will pass with transaction.
Below you can see a retrofit api code sample to send POST request to generateChecksum.php.
//this is the URL of the paytm folder that we added in the server
//make sure you are using your ip else it will not work
String BASE_URL = "http://192.168.101.1/paytm/";
#FormUrlEncoded
#POST("generateChecksum.php")
Call<Checksum> getChecksum(
#Field("MID") String mId,
#Field("ORDER_ID") String orderId,
#Field("CUST_ID") String custId,
#Field("CHANNEL_ID") String channelId,
#Field("TXN_AMOUNT") String txnAmount,
#Field("WEBSITE") String website,
#Field("CALLBACK_URL") String callbackUrl,
#Field("INDUSTRY_TYPE_ID") String industryTypeId
);
This part is very important you have to send all the parameters. And order_id should be unique everytime.
Source: Paytm Integration in Android Example
You need to pass only 8 param for checksum generation from SDK 2.0 and later. On Earlier version you need to pass email and mobile number too. Now there is no use of these param. First upload PHP file on your server and change the merchant key on config.php file inside lib folder. Now from android use can use retrofit or volley or httpconnection request to get checksum from your server. Here i am using Httpconnection (in this code JSONParse is a separate java class to call httpconnection). You can get reference on this link -http://www.blueappsoftware.in/android/blog/paytm-integration-sdk-2-1-android/
public class sendUserDetailTOServerdd extends AsyncTask<ArrayList<String>, Void, String> {
private ProgressDialog dialog = new ProgressDialog(checksum.this);
private String orderId , mid, custid, amt;
String url ="http://www.blueappsoftware.com/payment/payment_paytm/generateChecksum.php";
String varifyurl = // "https://securegw.paytm.in/theia/paytmCallback?ORDER_ID=<ORDER_ID>"; //
"https://pguat.paytm.com/paytmchecksum/paytmCallback.jsp";//
String CHECKSUMHASH ="";
#Override
protected void onPreExecute() {
this.dialog.setMessage("Please wait");
this.dialog.show();
// initOrderId();
orderId ="KK100343"; // NOTE : order id must be unique
mid = "blueap01867059473586"; // CREATI42545355156573
custid = "KKCUST0342";
}
protected String doInBackground(ArrayList<String>... alldata) {
// String url ="http://xxx.co.in/generateChecksum.php";
JSONParser jsonParser = new JSONParser(checksum.this);
String param=
"MID="+mid+
"&ORDER_ID=" + orderId+
"&CUST_ID="+custid+
"&CHANNEL_ID=WEB&TXN_AMOUNT=100&WEBSITE=www.blueappsoftware.in"+"&CALLBACK_URL="+ varifyurl+"&INDUSTRY_TYPE_ID=Retail";
Log.e("checksum"," param string "+param );
JSONObject jsonObject = jsonParser.makeHttpRequest(url,"POST",param);
// yaha per checksum ke saht order id or status receive hoga..
Log.e("CheckSum result >>",jsonObject.toString());
if(jsonObject != null){
Log.e("CheckSum result >>",jsonObject.toString());
try {
CHECKSUMHASH=jsonObject.has("CHECKSUMHASH")?jsonObject.getString("CHECKSUMHASH"):"";
Log.e("CheckSum result >>",CHECKSUMHASH);
} catch (JSONException e) {
e.printStackTrace();
}
}
return CHECKSUMHASH;
}
#Override
protected void onPostExecute(String result) {
// jab run kroge to yaha checksum dekhega
///ab service ko call krna hai
Log.e(" setup acc "," signup result " + result);
if (dialog.isShowing()) {
dialog.dismiss();
}}
Step 2) now onPostExceute method you have checksum as result. It's time to call paytm staging service and call start transaction. Below is code to call paytm service
PaytmPGService Service =PaytmPGService.getStagingService();
// when app is ready to publish use production service
// PaytmPGService Service = PaytmPGService.getProductionService();
// now call paytm service here
//below parameter map is required to construct PaytmOrder object, Merchant should replace below map values with his own values
Map<String, String> paramMap = new HashMap<String, String>();
//these are mandatory parameters
// ye sari valeu same hon achaiye
//MID provided by paytm
paramMap.put("MID", mid);
paramMap.put("ORDER_ID", orderId);
paramMap.put("CUST_ID", custid);
paramMap.put("CHANNEL_ID", "WEB");
paramMap.put("TXN_AMOUNT", "100");
paramMap.put("WEBSITE", "www.blueappsoftware.in");
paramMap.put("CALLBACK_URL" ,varifyurl);
//paramMap.put( "EMAIL" , "abc#gmail.com"); // no need
// paramMap.put( "MOBILE_NO" , "9144040888"); // no need
paramMap.put("CHECKSUMHASH" ,CHECKSUMHASH);
//paramMap.put("PAYMENT_TYPE_ID" ,"CC"); // no need
paramMap.put("INDUSTRY_TYPE_ID", "Retail");
PaytmOrder Order = new PaytmOrder(paramMap);
Log.e("checksum ", paramMap.toString());
Service.initialize(Order,null);
// start payment service call here
Service.startPaymentTransaction(checksum.this, true, true, checksum.this );
what is new ConfirmMerchent().execute();
and in docs
after merchent verify check again this uri for payment confirmation
https://secure.paytm.in/oltp/HANDLER_INTERNAL/TXNSTATUS
I am working on basecamp OAuth 2.0 integration in my android app.
https://github.com/basecamp/api/blob/master/sections/authentication.md#get-authorization
I am following below Documentation for implementation.
The library for get accesstoken and all is below.
https://github.com/dmfs/oauth2-essentials
I done with below things
// Create OAuth2 provider
OAuth2AuthorizationProvider provider = new BasicOAuth2AuthorizationProvider(
URI.create("https://launchpad.37signals.com/authorization/new"),
URI.create("https://launchpad.37signals.com/authorization/token"),
new Duration(1,0,3600)
OAuth2ClientCredentials credentials = new BasicOAuth2ClientCredentials(
"client-id //from >https://integrate.37signals.com/", "client-secret" // From >https://integrate.37signals.com/);
// Create OAuth2 client
OAuth2Client client = new BasicOAuth2Client(
provider,
credentials,
URI.create("https://example.com/sandbox97/basecampoauth/basecamploginresponse") //this is from "https://integrate.37signals.com/"/* Redirect URL */);
// Start an interactive Authorization Code Grant
OAuth2InteractiveGrant grant = new AuthorizationCodeGrant(
client, new BasicScope("scope"));
// Get the authorization URL and open it in a WebView
URI authorizationUrl = grant.authorizationUrl();
Now when i open above url in webview it will return with
"https://example.com/sandbox97/basecampoauth/basecamploginresponse?code=12345678&state=**********h9JKj_KvpVo-oiMe_5*****************yLeIb******* "
Then After as per instruction i will call
// Open the URL in a WebView and wait for the redirect to the redirect URL
// After the redirect, feed the URL to the grant to retrieve the access token
OAuth2AccessToken token = grant.withRedirect(redirectUrl).accessToken(executor);
Like in my code
public class getToken extends AsyncTask<String, Void, String> {
String lsUrl;
public getToken(String fsUrl) {
lsUrl = fsUrl;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.i(TAG, "onPreExecute called");
}
#Override
protected String doInBackground(String... params) {
HttpRequestExecutor executor = new HttpUrlConnectionExecutor();
try {
OAuth2AccessToken token = null;
try {
token = grant.withRedirect(new URI(lsUrl)).accessToken(executor);
} catch (URISyntaxException e) {
e.printStackTrace();
}
Log.i(TAG, "token token token token> " + token);
s = String.valueOf(token);
} catch (IOException e) {
e.printStackTrace();
} catch (ProtocolError protocolError) {
protocolError.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
}
Log.i(TAG, "token token token token> s " + s);
return s;
}
#Override
protected void onPostExecute(String aVoid) {
super.onPostExecute(aVoid);
Log.i(TAG, "onPostExecute called" + aVoid);
}
}
when i execute the task i will get null value always.
and got the below error in log console.
11-21 18:21:16.731 25798-25798/com.myApp I/chromium: [INFO:CONSOLE(22)]
"Uncaught TypeError: Cannot read property 'postMessage' of null", source:
https://example.com/sandbox97/basecampoauth/basecamploginresponse?
code=12345678&state=**********h9JKj_KvpVo-oiMe_5*****************yLeIb******* (22)
i tried both way- using library and using scratch as per documentation. but every time i get null response when i try to get access token from the url.
Please help me out from this. i am stuck from more than 2 days.
For my application, I need token for logging in with google plus. Now, I dont know where to get the token. Is google plus token the same as gcm token?
you need to read this section of the docs about how to get an auth key to send to your server
https://developers.google.com/identity/sign-in/android/backend-auth
private class GetIdTokenTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
String accountName = Plus.AccountApi.getAccountName(mGoogleApiClient);
Account account = new Account(accountName, GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
String scopes = "audience:server:client_id:" + SERVER_CLIENT_ID; // Not the app's client ID.
try {
return GoogleAuthUtil.getToken(getApplicationContext(), account, scopes);
} catch (IOException e) {
Log.e(TAG, "Error retrieving ID token.", e);
return null;
} catch (GoogleAuthException e) {
Log.e(TAG, "Error retrieving ID token.", e);
return null;
}
}
#Override
protected void onPostExecute(String result) {
Log.i(TAG, "ID token: " + result);
if (result != null) {
// Successfully retrieved ID Token
// ...
} else {
// There was some error getting the ID Token
// ...
}
}
}
I am getting an error from the token I am receiving through google sign in android:
{ "error": "invalid_token", "error_description": "Invalid Value" }
I also noticed that my token looks a bit short compared to the one I am getting in iOS:
ya29.4AFYx2XNZ1sdfdzhWo-of-fSpsDPjgmATx-J82mCjqZJXglwj8VOvedpY_YXJgEVIWe
I am getting the token like this:
private class RetrieveTokenTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
String accountName = params[0];
String scopes = "oauth2:profile email";
String token = null;
try {
token = GoogleAuthUtil.getToken(getActivity().getApplicationContext(), accountName, scopes);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} catch (UserRecoverableAuthException e) {
//startActivityForResult(e.getIntent(), REQ_SIGN_IN_REQUIRED);
} catch (GoogleAuthException e) {
Log.e(TAG, e.getMessage());
}
return token;
}
#Override
protected void onPostExecute(String token) {
super.onPostExecute(token);
Log.i("Token Value: ", token);
}
}
Any idea what might be happening, or how to debug more in depth the problem?
Ok so I found the answer, the scopes must be written like this:
String scopes = "oauth2:"
+ Scopes.PLUS_LOGIN
+ " "
+ Scopes.PROFILE;
And the endpoint differs from android to iOS
'https://www.googleapis.com/oauth2/v1/tokeninfo?id_token='; //for iOS
'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='; //for android
I'm developing an android app which requires the use of a webservice to verify a user's credentials . The webpage link contains the following data :
{"userid":"752","success":1,"fail":0}
How to verify the user on the basis of this response?
First, you have to make a class for this response:
LoginDataClass.java
public class LoginDataClass {
public String userid, success, fail;
}
Then you have to parse this JSON and store in login data class:
public class DataParsingClass {
static String Url;
public static String Result;
static JSONObject jsonString, subString;
public static ArrayList<NameValuePair> nameValuePairs;
public static void LoginData() {
Url ="PUT YOUR LOGIN API";
Result = HttpClass.getData(Url);
try {
jsonString = new JSONObject(Result);
if (jsonString.length() > 0) {
if (jsonString.has("userid")) {
LoginDataClass.userid= jsonString
.getString("userid");
}
if (jsonString.has("success")) {
LoginDataClass.success= jsonString
.getString("success");
}
if (jsonString.has("fail")) {
LoginDataClass.fail= jsonString
.getString("fail");
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Using the above, you can store your response in a class object. When you have to check if the login was successful or not, use this in your main activity where you call the login API:
LoginDataClass ObjLogin = new LoginDataClass();
if(ObjLogin.success.equals("1"))
{
// write u want to do after login
}
else{
dialog display login fail
}