I am integrating PayTM in my app which is in ios (Swift) and I am facing issue which title is "Transaction Failed" and the message is "MissingKeys"
I have used following code
merchant = PGMerchantConfiguration.default()!
merchant.checksumGenerationURL = "http://getlook.in/cgi-bin/checksum_generate.cgi"
merchant.checksumValidationURL = "http://getlook.in/cgi-bin/checksum_validate.cgi"
merchant.clientSSLCertPath = nil
merchant.clientSSLCertPassword = nil
merchant.merchantID = "rriver57770575448885"
merchant.website = "APP_STAGING"
merchant.industryID = "Retail"
merchant.channelID = "WAP"
var orderDict = [String: String]()
orderDict["MID"] = "rriver57770575448885" // Merchant ID
orderDict["CHANNEL_ID"] = "WAP" // Channel Id
orderDict["INDUSTRY_TYPE_ID"] = "Retail" // Industry Type
orderDict["WEBSITE"] = "APP_STAGING"
orderDict["TXN_AMOUNT"] = "10"; // amount to charge // mandatory
orderDict["ORDER_ID"] = "\(Date().timeIntervalSince1970)";//change order id every time on new transaction
orderDict["REQUEST_TYPE"] = "DEFAULT";// remain same
orderDict["CUST_ID"] = "123456789027"; // change acc. to your database user/customers
orderDict["MOBILE_NO"] = "8798987874";// optional
orderDict["EMAIL"] = "test#paytm.com"; //optional
let pgOrder = PGOrder(params: orderDict)
let transaction = PGTransactionViewController.init(transactionFor: pgOrder)
transaction?.serverType = eServerTypeProduction
transaction?.merchant = merchant
transaction?.loggingEnabled = true
transaction?.delegate = self
self.present(transaction!, animated: true, completion: nil)
please help!
In this code you have missed a parameter called chechSumHash. include that too.
orderDict["CHECKSUMHASH"] = CheckSum;
checkSumHash can be generated in the backend by the help of Paytm checksum generation kit. the checksum is a unique string which will change according to the parameter that we have send for checksum generation Api
Related
I am trying to update an item in my dynamoDB noSQL database. Having some troubles implementing this in swift as there is no swift documentation yet.
I was able to create an item in the database successfully, updating an item seems to be a whole other monster.
Swift Code:
var updatedValue: AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue()
updatedValue.s = self.UserID
let dynamo: AWSDynamoDB = AWSDynamoDB()
let AddToHistory = Users()
AddToHistory?._campany = self.CompanyTextBox.text!
AddToHistory?._personalSite = self.PersonalTitleTextBox.text!
AddToHistory?._facebook = self.FacebookTextBox.text!
AddToHistory?._linkedIn = self.LinkedInTextBox.text!
AddToHistory?._title = self.TitleTextBox.text!
AddToHistory?._bio = self.BioTextBox.text!
let updateInput: AWSDynamoDBUpdateItemInput = AWSDynamoDBUpdateItemInput()
updateInput.tableName = "myTableName"
updateInput.key = ["_userId": updatedValue]
let updatedCompany = AWSDynamoDBAttributeValue()
updatedCompany?.s = AddToHistory?._campany
let updatedFacebook = AWSDynamoDBAttributeValue()
updatedFacebook?.s = AddToHistory?._facebook
let updatedLinkedIn = AWSDynamoDBAttributeValue()
updatedLinkedIn?.s = AddToHistory?._linkedIn
let updatedPersonalSite = AWSDynamoDBAttributeValue()
updatedPersonalSite?.s = AddToHistory?._personalSite
let updatedTitle = AWSDynamoDBAttributeValue()
updatedTitle?.s = AddToHistory?._title
let updatedBio = AWSDynamoDBAttributeValue()
updatedBio?.s = AddToHistory?._bio
updateInput.expressionAttributeValues = [
"_campany" : updatedCompany!,
"_facebook" : updatedFacebook!,
"_linkedIn" : updatedLinkedIn!,
"_personalSite" : updatedPersonalSite!,
"_title" : updatedTitle!,
"_bio" : updatedBio!,
]
updateInput.returnValues = AWSDynamoDBReturnValue.updatedNew
dynamo.updateItem(updateInput).continueOnSuccessWith(block: { (task:AWSTask!) -> AnyObject! in
if (task.error == nil) {
}
return nil
}
)
Not getting any warnings or errors in the editor, however when I run the app and press the button which runs this code, I get this exception thrown:
Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: '- init is not a valid
initializer. Use + defaultDynamoDB or + DynamoDBForKey: instead.'
Not sure what I am missing here, it must be something to do with the way I am initializing the dynamoDB object. Tried accessing a default method for init, but there is no such method. :(
Any help would be greatly appreciated, thanks in advance!
Thanks to Jake.lange's comment, I realized I could have used the object mapper that i used to create items to update them as well. Heres the code incase others run into this problem :)
//db connection mapper
let objectMapper = AWSDynamoDBObjectMapper.default()
//new instancer of User class
let itemToUpdate:CheckaraUsers = CheckaraUsers()
//populate
itemToUpdate._userId = UserID
itemToUpdate._firstName = FirstName
itemToUpdate._lastName = LastName
itemToUpdate._campany = AddToHistory?._campany
itemToUpdate._facebook = AddToHistory?._facebook
itemToUpdate._linkedIn = AddToHistory?._linkedIn
itemToUpdate._personalSite = AddToHistory?._personalSite
itemToUpdate._title = AddToHistory?._title
itemToUpdate._bio = AddToHistory?._bio
//save to dynamoDB
objectMapper.save(itemToUpdate, completionHandler:{(error: Error?) -> Void in
if let error = error {
print("Amazon DynamoDB Save Error: \(error)")
}
print("Saved Information!!!")
})
Your definition was wrong.
Change this:
let dynamo: AWSDynamoDB = AWSDynamoDB()
to:
let dynamo: AWSDynamoDB = AWSDynamoDB.default()
This question already has answers here:
type 'Any' has no subscript members
(2 answers)
Closed 5 years ago.
i know to much ask like this. i already searching but not match with my problems.
oke i will try explain with my code
i have data API Like this
["profile": {
accountId = 58e470a0c50472851060d083;
androidDeviceId = "[\"3453247ddcf3f809\"]";
androidVersion = 21;
appId = (
"c46b4c10-62ce-11e6-bdd4-59e4df4b8410",
"fac915f0-fe2b-11e6-9dfb-55339bd7be35"
);
appVersion = "v5.1.0";
avatar = "https://account.8villages.com/uploads/images/5/1491366164_bnx1t0rudi.jpg";
birthDate = "12/03/1994";
"channel-group" = android;
communityId = 553e09b251906884443eff85;
coordinates = {
coordinates = (
"106.9602383333333",
"-6.249333333333334"
);
type = Point;
};
crop = "";
crops = "<null>";
customerId = 5369bd85cae84d0e03246a7c;
dateSubmitted = {
iso = "2017-04-05T04:20:48.483Z";
timestamp = 1491366048;
};
fullName = "Megi Fernanda";
gender = "Laki-laki";
homeAddress = Payakumbuah;
location = "Kota Payakumbuh";
moderation = {
at = {
iso = "2017-04-05T04:20:48.483Z";
timestamp = 1491366048;
};
by = auto;
status = moderated;
};
skill = "Budidaya pertanian";
state = "Sumatera Barat";
storeType = "";
subdistrict = "Payakumbuh Barat";
totalConversations = {
articles = 0;
forums = 0;
questions = 2;
responses = 0;
storeItems = 1;
};
type = users;
university = "Politeknik Negeri Pertanian Payakumbuh";
}, "accessToken": {
key = "lH5aYvnp2JAZ6zoKQK4mpfsxCI0.";
secret = "yfZfTZbsaVIhKCbksGHQnPcPg9mKtoRAKyvjg_cgMeo.";
}]
i already can got fullName, Addres, Skill State etc
if let profile = json["profile"] as? NSDictionary {
let name = profile["fullName"]
let alamat = profile["Skill"]
}
but i don't know how to get atribut in totalConversation like question, storeItems, points
skill = "Budidaya pertanian";
state = "Sumatera Barat";
storeType = "";
subdistrict = "Payakumbuh Barat";
totalConversations = {
articles = 0;
forums = 0;
questions = 2;
responses = 0;
storeItems = 1;
};
i tried like
let profile = json["profile"]["totalConversation"] as? NSDictionary
error sign : Type 'any?' has no subscript members
You got that error because json["profile"] is Any type and it doesn't have any subscript. So you need to cast json["profile"] to a dictionary, [String: Any] is dictionary type in Swift.
if let profile = json["profile"] as? [String: Any] {
if let totalConversations = profile["totalConversations"] as? [String: Any] {
let questions = totalConversations["questions"] as? Int
}
}
I'm using RTCDataChannel. But messages which i'm sending through the channel are not receiving at the other peer.
Here is the code:
let audioConstraint : RTCPair = RTCPair(key: "OfferToReceiveAudio", value: "true")
let videoConstraint : RTCPair = RTCPair(key: "OfferToReceiveVideo", value: "true")
let dtlsConstraint : RTCPair = RTCPair(key: "DtlsSrtpKeyAgreement", value: "true")
let mediaContraints : RTCMediaConstraints = RTCMediaConstraints(mandatoryConstraints: [audioConstraint, videoConstraint], optionalConstraints: [ dtlsConstraint])
RTCPeerConnectionFactory.initializeSSL()
peerConnection = peerConnectionFactory.peerConnectionWithICEServers(servers, constraints: mediaContraints, delegate: self)
dataChannels = peerConnection?.createDataChannelWithLabel(channelName,config: nil)
dataChannels?.delegate = self
var message : NSData = NSData(base64EncodedString: "helloo")
var buffer : RTCDataBuffer = RTCDataBuffer(data: message, isBinary: true)
dataChannels?.sendData(buffer)
Have you resolved it?
One of the two peers should create data channel and other should attach the received data channel object to its data channel object.
The initiator should create datachannel before sending offer. Hope this might be helpful
I had the same problem until I set the option not to nil. If I skipped the steamId, it would not send. Even though the channel is open.
RTCDataChannelInit *dataInit = [[RTCDataChannelInit alloc] init];
dataInit.isNegotiated = YES;
dataInit.isOrdered = YES;
dataInit.maxRetransmits = 30;
dataInit.maxRetransmitTimeMs = 30000;
dataInit.streamId = 12; //important setting
self.dataChannel = [_peerConnection createDataChannelWithLabel:kRTCDataChannelLabel config:dataInit];
self.dataChannel.delegate = self;
I can perform a simple Get request on a singular table within AWS dynamoDB however when I expand it to a Batch Request across multiple tables I continue to get a error
validation error detected: Value null at 'requestItems.rip.member.keys' failed to satisfy constraint
I understand this as the values not being passed correctly but I can't see what the issue is with my code
//Create Request Values
AWSDynamoDBGetItemInput *getItem = [AWSDynamoDBGetItemInput new];
AWSDynamoDBAttributeValue *hashValue = [AWSDynamoDBAttributeValue new];
hashValue.S = #"User Test";
getItem.key = #{#"ripId": hashValue};
//Create Request Values 2
AWSDynamoDBGetItemInput *getItem2 = [AWSDynamoDBGetItemInput new];
AWSDynamoDBAttributeValue *hashValue2 = [AWSDynamoDBAttributeValue new];
hashValue2.S = #"User Test";
getItem2.key = #{#"chat": hashValue2};
//Combine to Batch Request
AWSDynamoDBBatchGetItemInput * batchFetch = [AWSDynamoDBBatchGetItemInput new];
batchFetch.requestItems = #{ #"rip": getItem,
#"chat": getItem,};
[[dynamoDB batchGetItem:batchFetch] continueWithBlock:^id(BFTask *task) {
if (!task.error) {
NSLog(#"BOY SUCCES");
} else {
NSLog(#" NO BOY SUCCESS %#",task.error);
}
return nil;
}];
Searched the internet high and low but cannot see a working example of a batch request using iOS Objective C (or swift for that matter).
I have tested both variables on a single Get request and they both work.
You forgot to wrap around AWSDynamoDBAttributeValue in AWSDynamoDBKeysAndAttributes. Here is a simple example from AWSDynamoDBTests.m:
AWSDynamoDBKeysAndAttributes *keysAndAttributes = [AWSDynamoDBKeysAndAttributes new];
keysAndAttributes.keys = #[#{#"hashKey" : attributeValue1},
#{#"hashKey" : attributeValue2}];
keysAndAttributes.consistentRead = #YES;
AWSDynamoDBBatchGetItemInput *batchGetItemInput = [AWSDynamoDBBatchGetItemInput new];
batchGetItemInput.requestItems = #{table1Name: keysAndAttributes};
Since the batch get doesn't map to a class I solved it by doing this instead.
I solved it by doing this,
let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.defaultDynamoDBObjectMapper()
let task1 = dynamoDBObjectMapper.load(User.self, hashKey: "rtP1oQ5DJG", rangeKey: nil)
let task2 = dynamoDBObjectMapper.load(User.self, hashKey: "dbqb1zyUq1", rangeKey: nil)
AWSTask.init(forCompletionOfAllTasksWithResults: [task1, task2]).continueWithBlock { (task) -> AnyObject? in
if let users = task.result as? [User] {
print(users.count)
print(users[0].firstName)
print(users[1].firstName)
}
else if let error = task.error {
print(error.localizedDescription)
}
return nil
}
Swift 3
I was able to get the BatchGet request work with the following code. Hope this helps someone else who's struggling with the lack of Swift Docs.
This code assumes that you've configured your AWSServiceConfiguration in the AppDelegate application didFinishLaunchingWithOptions method.
let DynamoDB = AWSDynamoDB.default()
// define your primary hash keys
let hashAttribute1 = AWSDynamoDBAttributeValue()
hashAttribute1?.s = "NDlFRTdDODEtQzNCOC00QUI5LUFFMzUtRkIyNTJFNERFOTBF"
let hashAttribute2 = AWSDynamoDBAttributeValue()
hashAttribute2?.s = "MjVCNzU3MUQtMEM0NC00NEJELTk5M0YtRTM0QjVDQ0Q1NjlF"
let keys: Array = [["userID": hashAttribute1], ["userID": hashAttribute2]]
let keysAndAttributesMap = AWSDynamoDBKeysAndAttributes()
keysAndAttributesMap?.keys = keys as? [[String : AWSDynamoDBAttributeValue]]
keysAndAttributesMap?.consistentRead = true
let tableMap = ["Your-Table-Name" : keysAndAttributesMap]
let request = AWSDynamoDBBatchGetItemInput()
request?.requestItems = tableMap as? [String : AWSDynamoDBKeysAndAttributes]
request?.returnConsumedCapacity = AWSDynamoDBReturnConsumedCapacity.total
DynamoDB.batchGetItem(request!) { (output, error) in
if output != nil {
print("Batch Query output?.responses?.count:", output!.responses!)
}
if error != nil {
print("Batch Query error:", error!)
}
}
I have this json result.
I would take the field "alert".
I try this:
var alert: NSString = jsonResult["features"]["properties"]["alert"]
but this is the error: does not have a member named 'subscript'.
I can not how to access a field in a nested dictionary
{
features = (
{
geometry = {
coordinates = (
"-97.95359999999999",
"37.2382",
5
);
type = Point;
};
id = usb000si7g;
properties = {
alert = green;
cdi = "5.8";
code = b000si7g;
detail = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/usb000si7g.geojson";
dmin = "0.017";
felt = 1258;
gap = 38;
ids = ",usb000si7g,";
mag = "4.3";
magType = mwr;
mmi = "4.94";
net = us;
nst = "<null>";
place = "8km SE of Harper, Kansas";
rms = "0.51";
sig = 864;
sources = ",us,";
status = reviewed;
time = 1412272884590;
title = "M 4.3 - 8km SE of Harper, Kansas";
tsunami = "<null>";
type = earthquake;
types = ",cap,dyfi,general-link,geoserve,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,tectonic-summary,";
tz = "-300";
updated = 1412614943519;
url = "http://earthquake.usgs.gov/earthquakes/eventpage/usb000si7g";
};
type = Feature;
}
);
metadata = {
api = "1.0.13";
count = 1;
generated = 1412617232000;
status = 200;
title = "USGS Significant Earthquakes, Past Week";
url = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_week.geojson";
};
type = FeatureCollection;
}
I don't know what to do. swift is changed every beta.
As #Kirsteins said is his answer, you have to do a lot of unwrapping, and it's recommended to use a JSON library.
If you still want to stick with hand made extraction, then I suggest you to made it programmatically, such as adding an extension to NSDictionary as follows:
extension NSDictionary {
func objectForTreeKeys<T>(keys:[String]) -> T? {
var dict: NSDictionary? = self
var retValue: T?
for key in keys {
var value: AnyObject? = dict?.objectForKey(key)
if let unwrapped = value as? NSDictionary {
dict = unwrapped
} else if let unwrapped = value as? T {
retValue = unwrapped
break
} else {
retValue = nil
break
}
}
return retValue
}
}
You pass an array of keys to the function, and it traverses all nested dictionaries until:
a value of type T is encountered
a value having type different than NSDictionary and T is found
a nil value is found
In the first case, it returns the value of T type - in the other cases it returns nil.
You can use it as follows:
let ret: String? = jsonResult.objectForTreeKeys(["features", "properties", "alert"])
As you can see, it's a generic method, and the return type is inferred from the type of the variable the result is assigned to - so it's necessary to explicitly define its type, which must be optional (String? in this specific case).