Stripe integration in Kotlin App -- IllegalStateException - java

I am integrating Stripe for Java in a Kotlin app.
This is the code that I wrote to create a Charge
createCharge function:
fun createCharge(charge: Charge, testApiKey: String): Charge? {
//met
// On your server, grab the Stripe token in the POST parameters submitted by your form. From there, it’s one simple API call to charge the card
Stripe.apiKey = testApiKey
try {
val chargeParams = mutableMapOf<String, Any?>()
chargeParams["amount"] = charge.amount
chargeParams["currency"] = charge.currency
chargeParams["description"] = charge.description
chargeParams["source"] = charge.source
chargeParams["customer"] = charge.customer
chargeParams["receipt_email"] = charge.receiptEmail
val requestOptions = idempotencyKeySetter()
val initialMetadata = mutableMapOf<String, String?>()
initialMetadata["start_date"] = charge.metadata["start_date"]
initialMetadata["end_date"] = charge.metadata["end_date"]
chargeParams["metadata"] = initialMetadata
return Charge.create(chargeParams, requestOptions)
} catch (e: StripeException) {
e.printStackTrace()
return null
}
}
and the function calling the createCharge function:
var formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
fun checkCreateCharge() {
val chargeParams: Charge = Charge()
chargeParams.amount = 2000
chargeParams.currency = "usd"
chargeParams.description = description
chargeParams.source = PaymentSource { "" }
chargeParams.customer = customerId
chargeParams.receiptEmail = testEmail
chargeParams.metadata["start_date"] = LocalDate.parse("2018-12-31", formatter).toString()
chargeParams.metadata["end_date"] = LocalDate.parse("2019-03-31", formatter).toString()
val newCharge: Charge? = createCharge(chargeParams, testApiKey)
}
When I the function checkCreateCharge runs, it sends the following error:
java.lang.IllegalStateException: chargeParams.metadata must not be null
Does anyone know why this is the case?

So while this is "possible" you absolutely should not do this. It's a very large security vulnerability. Anyone with your App would be able to sniff your Stripe Secret API Key and do any number of bad things. They could, for instance, test credit cards or even take money from your account.
When implementing Stripe on Android you should only use your Publishable API Key and only use the key to create Tokens/Sources. All other operations should leverage your Secret API Key on a secured backend.

Best I can tell from the API documentation, you're accessing getMetadata() which is returning null (as you've never set a value on it). Basically, the line:
chargeParams.metadata["start_date"] = LocalDate.parse("2018-12-31", formatter).toString()
is equivalent to the Java code:
chargeParams.getMetadata().put("start_date", LocalDate.parse("2018-12-31", formatter).toString())
and in your situation getMetadata() is null. I believe changing this to be:
chargeParams.setMetadata(
mapOf(
"start_date" to LocalDate.parse("2018-12-31", formatter).toString(),
"end_date" to LocalDate.parse("2019-03-31", formatter).toString()
)
)
will resolve the issue.

Related

kotlin android get deleted value from realm-java

I use realm-java on Android. now I'm creating profile function, but I'm not sure how to user realm correctly.
when renew profile,
delete value -> store value
but, I fetch value from realm, sometimes old value is taken.
To reproduce,
My test repository is below, and I attached movie that problem is reproduced.
https://github.com/shinsan/realm_test/
When thread id is changed, sometimes old value appears.
so, if you try to reproduce, please use lower memory device such as nexus5 simulator
#I think Realm instance is singleton and transaction is thread-safe, so value is always only one.
my code
kotlin + Android Studio
Realm Java 10.3
//Store
val realm = Realm.getDefaultInstance()
realm.executeTransaction {
val entity = AccountProfileEntity(accountProfile)
it.copyToRealmOrUpdate(entity)
}
//Delete
val realm = Realm.getDefaultInstance()
val entity = realm.where(AccountProfileEntity::class.java).findFirst()
realm.executeTransaction {
entity?.deleteFromRealm()
}
//Fetch
val realm = Realm.getDefaultInstance()
val instance = realm.where(AccountProfileEntity::class.java).findFirst()
return instance?.toModel()
// profile get function
override suspend fun getProfile(isForce: Boolean): AccountProfile =
withContext(Dispatchers.IO) {
if (isForce) {
database.delete()
}
val profile = database.fetch()
if (profile != null) {
return#withContext profile
}
val token = prefs.getToken() ?: throw NoTokenException
val response = service.getProfile(token)
database.store(response)
response
}
Please Help
I solved this. simply I forgot to close realm instance each fetch, store, delete.

Retrieving info with linearId (simple query to a Corda node)

We are building a basic PoC example with Corda. Right now we have a basic Cordapp that send a String message from one node to another.
That works fine but next steps are to retrieve one message using the api.
We have this path to retrieve all, but we need just one.
#GET
#Path("cases")
#Produces(MediaType.APPLICATION_JSON)
public List<StateAndRef<CaseState>> getCases();
return rpcOps.vaultQuery(CaseState.class).getStates();
}
We have already tried like this:
#GET
#Path("cases/{caseId}")
#Produces(MediaType.APPLICATION_JSON)
public StateAndRef<CaseState> getCase(#PathParam("caseId") String caseId) throws InterruptedException, ExecutionException {
UniqueIdentifier id = new UniqueIdentifier.fromString("caseId");
QueryCriteria criteria = new QueryCriteria.LinearStateQueryCriteria(null, InmutableList.of(id), Vault.StateStatus.UNCONSUMED, null);
return rpcOps.vaultQueryBy(CaseState.class).queryBy(criteria).getStates().get(0);
}
Can you help me?
I have done this in my Cordapps by querying by unconsumed states of the wanted type and then simply filtering the returned result to get what is needed. For example, the following is an example of a Account state being filtered by linearID (as needed in your example)
//Query the vault for unconsumed states and then for account states
val criteria = QueryCriteria.VaultQueryCriteria(status = Vault.StateStatus.UNCONSUMED)
val customerStates = serviceHub.vaultService.queryBy<Account.State>(criteria)
//Filter the customer states to find a matching linearId
val filteredStates = customerStates.states.filter {
it.state.data.linearId == linearId
}
Hopefully this helps!
Trying to reconstruct the UniqueIdentifier from the externalId won't work, as you don't know what the UUID is.
The full constructor for LinearStateQueryCriteria is:
data class LinearStateQueryCriteria #JvmOverloads constructor(
val participants: List<AbstractParty>? = null,
val uuid: List<UUID>? = null,
val externalId: List<String>? = null,
override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED,
override val contractStateTypes: Set<Class<out ContractState>>? = null)
So you need to use the full constructor and query the vault using the following criteria:
QueryCriteria criteria = new QueryCriteria.LinearStateQueryCriteria(
null,
null,
ImmutableList.of("caseId"),
Vault.StateStatus.UNCONSUMED,
null);
Note how here, we're not specifying the UUID, but we are specifying the externalId.
You can use something like this
UUID linearId = "2be921da-5a79-4513-8cb3-7b87ea9307cf";
QueryCriteria criteria = new QueryCriteria.LinearStateQueryCriteria( null, Arrays.asList(linearId), null, Vault.StateStatus.UNCONSUMED, null);

How to perform Amazon Cloud Search with .net code?

I am learning Amazon Cloud Search but I couldn't find any code in either C# or Java (though I am creating in C# but if I can get code in Java then I can try converting in C#).
This is just 1 code I found in C#: https://github.com/Sitefinity-SDK/amazon-cloud-search-sample/tree/master/SitefinityWebApp.
This is 1 method i found in this code:
public IResultSet Search(ISearchQuery query)
{
AmazonCloudSearchDomainConfig config = new AmazonCloudSearchDomainConfig();
config.ServiceURL = "http://search-index2-cdduimbipgk3rpnfgny6posyzy.eu-west-1.cloudsearch.amazonaws.com/";
AmazonCloudSearchDomainClient domainClient = new AmazonCloudSearchDomainClient("AKIAJ6MPIX37TLIXW7HQ", "DnrFrw9ZEr7g4Svh0rh6z+s3PxMaypl607eEUehQ", config);
SearchRequest searchRequest = new SearchRequest();
List<string> suggestions = new List<string>();
StringBuilder highlights = new StringBuilder();
highlights.Append("{\'");
if (query == null)
throw new ArgumentNullException("query");
foreach (var field in query.HighlightedFields)
{
if (highlights.Length > 2)
{
highlights.Append(", \'");
}
highlights.Append(field.ToUpperInvariant());
highlights.Append("\':{} ");
SuggestRequest suggestRequest = new SuggestRequest();
Suggester suggester = new Suggester();
suggester.SuggesterName = field.ToUpperInvariant() + "_suggester";
suggestRequest.Suggester = suggester.SuggesterName;
suggestRequest.Size = query.Take;
suggestRequest.Query = query.Text;
SuggestResponse suggestion = domainClient.Suggest(suggestRequest);
foreach (var suggest in suggestion.Suggest.Suggestions)
{
suggestions.Add(suggest.Suggestion);
}
}
highlights.Append("}");
if (query.Filter != null)
{
searchRequest.FilterQuery = this.BuildQueryFilter(query.Filter);
}
if (query.OrderBy != null)
{
searchRequest.Sort = string.Join(",", query.OrderBy);
}
if (query.Take > 0)
{
searchRequest.Size = query.Take;
}
if (query.Skip > 0)
{
searchRequest.Start = query.Skip;
}
searchRequest.Highlight = highlights.ToString();
searchRequest.Query = query.Text;
searchRequest.QueryParser = QueryParser.Simple;
var result = domainClient.Search(searchRequest).SearchResult;
//var result = domainClient.Search(searchRequest).SearchResult;
return new AmazonResultSet(result, suggestions);
}
I have already created domain in Amazon Cloud Search using AWS console and uploaded document using Amazon predefine configuration option that is movie Imdb json file provided by Amazon for demo.
But in this method I am not getting how to use this method, like if I want to search Director name then how do I pass in this method as because this method parameter is of type ISearchQuery?
I'd suggest using the official AWS CloudSearch .NET SDK. The library you were looking at seems fine (although I haven't look at it any detail) but the official version is more likely to expose new CloudSearch features as soon as they're released, will be supported if you need to talk to AWS support, etc, etc.
Specifically, take a look at the SearchRequest class -- all its params are strings so I think that obviates your question about ISearchQuery.
I wasn't able to find an example of a query in .NET but this shows someone uploading docs using the AWS .NET SDK. It's essentially the same procedure as querying: creating and configuring a Request object and passing it to the client.
EDIT:
Since you're still having a hard time, here's an example. Bear in mind that I am unfamiliar with C# and have not attempted to run or even compile this but I think it should at least be close to working. It's based off looking at the docs at http://docs.aws.amazon.com/sdkfornet/v3/apidocs/
// Configure the Client that you'll use to make search requests
string queryUrl = #"http://search-<domainname>-xxxxxxxxxxxxxxxxxxxxxxxxxx.us-east-1.cloudsearch.amazonaws.com";
AmazonCloudSearchDomainClient searchClient = new AmazonCloudSearchDomainClient(queryUrl);
// Configure a search request with your query
SearchRequest searchRequest = new SearchRequest();
searchRequest.Query = "potato";
// TODO Set your other params like parser, suggester, etc
// Submit your request via the client and get back a response containing search results
SearchResponse searchResponse = searchClient.Search(searchRequest);

Json From .Net Server to android client

I'm trying to call a ApiController from android apllication.
This is the api controller:
[AcceptVerbs("GET", "POST")]
public string Get(string coords)
{
using (var context = new Entities())
{
var records = from poi in context.Pois
where poi.Latitude >= fromLatitude &&
poi.Latitude <= toLatitude &&
poi.Longitude >= fromLongitude &&
poi.Longitude <= toLongitude
select new
{
poiName = poi.Name,
poiLatitude = poi.Latitude,
poiLongitude = poi.Longitude
};
return JsonConvert(records);
}
}
}
private string JsonConvert(object records)
{
return Newtonsoft.Json.JsonConvert.SerializeObject(records,);
}
At the android code, I'm creating json array with new JSON(string).
The problem is java throws an excetpion: the json string is not valid.
When i look at the debuuger, I see that the string have 2 backslash before ",
and java dont know how to parse that.
Where is the problem?
Thank you
Update: Solved. The WebApi returned XML with the json as string. changed the WebApi Not to return XML, then changed it to return object (and removed the JSONConvert) - and it works.
I know this is an old question, but i had a similar problem and found a solution.
In my case i had to pass a complex JSON object (nested) from a .NET Client to a Java Rest API and was using a string parameter which turned out to be an invalid JSON due to the double backslash (I seralized it so it was escaped and then .NET escaped it again before sending).
So, in order to avoid that i used StringContent
MyType obj = new MyType()
{
...
};
string obJSON = JsonConvert.SerializeObject(obj);
StringContent sc = new StringContent(obJSON, Encoding.UTF8,"application/json");
HttpResponseMessage response = client.PostAsync(ruta, sc).Result;
Hope this helps someone!

How do I get all the calendar entries for a particular time range using Google Calendar API

I want to view events over specific time range for a specific calendar, but am having trouble using the API, It is a generic API, and it reminds me of using the DOM. The problem is that it seems difficult to work with because much of the information is in generic base classes.
How do I get the events for a calendar using Groovy or Java?
Does anybody have an example of passing credentials using curl?
Example code would be appreciated.
This document has examples for most of the common use cases. For example, here's the code for retrieving events for a specific time range
URL feedUrl = new URL("http://www.google.com/calendar/feeds/default/private/full");
CalendarQuery myQuery = new CalendarQuery(feedUrl);
myQuery.setMinimumStartTime(DateTime.parseDateTime("2006-03-16T00:00:00"));
myQuery.setMaximumStartTime(DateTime.parseDateTime("2006-03-24T23:59:59"));
CalendarService myService = new CalendarService("exampleCo-exampleApp-1");
myService.setUserCredentials("jo#gmail.com", "mypassword");
// Send the request and receive the response:
CalendarEventFeed resultFeed = myService.query(myQuery, Feed.class);
You could make this a bit Groovier, using something like:
def myQuery = new CalendarQuery("http://www.google.com/calendar/feeds/default/private/full".toURL()).with {
minimumStartTime = DateTime.parseDateTime("2006-03-16T00:00:00");
maximumStartTime = DateTime.parseDateTime("2006-03-24T23:59:59");
it
}
def myService = new CalendarService("exampleCo-exampleApp-1");
myService.setUserCredentials("jo#gmail.com", "mypassword");
// Send the request and receive the response:
def resultFeed = myService.query(myQuery, Feed);
If you do not need to alter the calendar, you only need to get the calendars private feed url, and you can use something like this (taken from the http://eu.gr8conf.org/agenda page). It uses the ICal4J library.
def url = "http://www.google.com/calendar/ical/_SOME_URL_/basic.ics".toURL()
def cal = Calendars.load(url)
def result = cal.components.sort { it.startDate.date }.collect {
def e = new Expando()
e.startDate = it.startDate.date
e.endDate = it.endDate.date
e.title = it.summary.value
if (it.location) {
e.presentation = Presentation.findByName(it.location.value, [fetch:"join"])
}
e.toString = {
"$startDate: $title"
}
return e
}
result
Happy hacking.

Categories