iOS ISO-8583消息发送

时间:2014-12-01 21:40:15

标签: ios iphone message server iso

我是iOS开发人员。我需要通过套接字服务器以ISO-8583标准发送消息。

我已与服务器建立连接,并且运行良好。 服务器以这种方式工作:当消息以正确的格式出现时(但数据不正确,例如错误的PIN),它会以适当的错误代码响应。当消息格式错误时,服务器根本没有响应;)

因此,知道我的连接工作正常(已测试),我有以下问题: 我需要向服务器发送ISO8583消息。消息必须包含以下字段:

  • SI (2个字节 - 整个邮件的大小)
  • TPDU (必须是12345 - 文档说)
  • 明细(以下详细信息)
  • EOT (规范 - 签署" 0D")

在下面的示例中,我们使用:

  • MTI - 0200
  • 帐号 - 6019 5300 0601 9592
  • 代码 - 700000
  • 终端ID - 35959551
  • PIN - 880088(需要有两个SPACES到底(文档说))

以下是文档规范:

  • 字段2 - 卡号,长度 - 19(3长+ 16号),格式 LLVAR
  • 字段3 - 处理代码,长度为6,格式为NUMBER
  • 字段12 - 时间(hhmmss),长度 - 6,格式NUMBER
  • 字段13 - 日期(mmdd),长度 - 4,格式NUMBER
  • 字段41 - 终端ID,长度 - 8,格式ALPHANUMERICAL
  • 字段52 - PIN,长度 - 16,格式HEX

因此,必须设置字段2,3,12,13,41和52。

我使用了两种方法:

1)使用外部库:https://github.com/mordoskull/Objective-ISO8583 - 使用许多不同的数据组合,它不起作用。我的用法:

   ISOMessage *isoMessage1 = [[ISOMessage alloc] init];
   NSString *tpdu = @"0102030405";
  [isoMessage1 setMTI:@"0200"];
  isoMessage1.bitmap = [[ISOBitmap alloc] initWithGivenDataElements:@[@"DE02", @"DE03", @"DE12", @"DE13", @"DE41", @"DE52"] configFileName:nil];
  [isoMessage1 addDataElement:@"DE02" withValue:cardNumber configFileName:nil];
  [isoMessage1 addDataElement:@"DE03" withValue:@"700000" configFileName:nil];
  [isoMessage1 addDataElement:@"DE12" withValue:transactionTime configFileName:nil];
  [isoMessage1 addDataElement:@"DE13" withValue:transactionDate configFileName:nil];
  [isoMessage1 addDataElement:@"DE41" withValue:@"35959551" configFileName:nil];  //TID - 35959551
  [isoMessage1 addDataElement:@"DE52" withValue:@"880088" configFileName:nil];

2)手动设置所有字段:

//CARD NUMBER
NSData *card = [cardNumber dataUsingEncoding:NSUTF8StringEncoding];

//TPDU
NSMutableData *TPDU = [[NSMutableData alloc] init];
[TPDU appendBytes:"\x01\x02\x03\x04\x05" length:5];

//TRANSACTION CODE
NSData *transactionCode = [[NSString stringWithFormat:@"%x",700000] dataUsingEncoding:NSUTF8StringEncoding];

//TIME AND DATE
NSData *time = [[NSString stringWithFormat:@"%x",[transactionTime intValue]] dataUsingEncoding:NSUTF8StringEncoding];
NSData *date = [[NSString stringWithFormat:@"%x",[transactionDate intValue]] dataUsingEncoding:NSUTF8StringEncoding];

//PIN
NSData *PIN = [[NSString stringWithFormat:@"%@  ",self.pinField.text] dataUsingEncoding:NSASCIIStringEncoding];

//TID
NSData *TID = [@"35959551" dataUsingEncoding:NSASCIIStringEncoding];

//MTI
NSMutableData *MTI = [[NSMutableData alloc] init];
[MTI appendBytes:"\x02\x00" length:2];

//BITMAP
NSArray* fields = [NSArray arrayWithObjects:@2, @3,
                   @12, @13, @41, @52, nil];
NSMutableArray* binary = [NSMutableArray new];
for(int i=0 ; i<64 ; ++i) {
    binary[i] = @"0";
}
for(int j = 0; j<[fields count]; ++j)
{
    binary[[fields[j] intValue]-1] = @"1";
}

NSMutableString * bitmap = [[NSMutableString alloc] init];
for (NSObject * obj in binary)
{
    [bitmap appendString:[obj description]];
}
NSData *bitmapByte = [bitmap dataUsingEncoding:NSUTF8StringEncoding];

NSMutableData *request = [[NSMutableData alloc] init];
[request appendData:TPDU];
[request appendData:MTI];
[request appendData:bitmapByte];
[request appendData:card];
[request appendData:transactionCode];
[request appendData:time];
[request appendData:date];
[request appendData:TID];
[request appendData:PIN];

NSData *SI = [[NSString stringWithFormat:@"00%lu",(unsigned long)[request length]] dataUsingEncoding:NSUTF8StringEncoding];

NSMutableData* fullRequest = [[NSMutableData alloc] init];
[fullRequest appendData:SI];
[fullRequest appendData:request];

我知道卡号字段必须在其前面附加三位数长度,并且我知道其他所有关于ISO8583的规格。

我设法在Log中获得看起来像这样的NSData:

Printing description of fullRequest:
<30303131 39010203 04050200 30313130 30303030 30303031 31303030 30303030 30303030 30303030     30303030 30303030 30303030 31303030 30303030 30303031 30303030 30303030 30303030 30313636 30313935     33303030 36303139 35393261 61653630 31393232 37346231 33353935 39353531 38383030 38382020>

The same message, not converted to NSData, looks like this : 
009001020304050200601800000080100001660195300060195927000001131041201359595513838303038382020

服务器根本没有响应,所以我必须发送错误的格式化消息。

有人可以帮助我正确格式化消息吗?

1 个答案:

答案 0 :(得分:0)

最后设法做到了myslef。这是一个用于设置参数的代码(如果有人需要它):

NSDate * currentTime = [NSDate date];     NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];

//get current Time
[dateFormatter setDateFormat:@"hhmmss"];
NSString *transactionTime = [dateFormatter stringFromDate: currentTime];
transactionTime = [transactionTime stringByReplacingOccurrencesOfString:@":" withString:@""];

//get current Date
[dateFormatter setDateFormat:@"MMdd"];
NSString *transactionDate = [dateFormatter stringFromDate:currentTime];

NSString* cardNumber = [[NSUserDefaults standardUserDefaults] objectForKey:@"cardNumber"];

//TID
NSData *TID = [@"35959551" dataUsingEncoding:NSASCIIStringEncoding];
//PIN
NSData *PIN = [[NSString stringWithFormat:@"%@",self.pinField.text] dataUsingEncoding:NSASCIIStringEncoding];
//TPDU
NSMutableData *TPDU = [[NSMutableData alloc] init];
[TPDU appendBytes:"\x01\x02\x03\x04\x05" length:5];
//MTI
NSMutableData *MTI = [[NSMutableData alloc] init];
[MTI appendBytes:"\x02\x00" length:2];
//TRANSACTION CODE
NSString *transactionCode = @"700000";
NSData *trCode = [self convertToData:transactionCode];
//CARD NUMBER
NSString *cardWithLength = [@"16" stringByAppendingString:cardNumber];
NSData *card = [self convertToData:cardWithLength];
//TIME AND DATE
NSData *time = [self convertToData:transactionTime];
NSData *date = [self convertToData:transactionDate];
//BITMAP
NSString *mapa = @"6018000000801000";
NSData *mapaData = [self convertToData:mapa];

NSMutableData *request = [[NSMutableData alloc] init];
[request appendData:TPDU];
[request appendData:MTI];
[request appendData:mapaData];
[request appendData:card];
[request appendData:trCode];
[request appendData:time];
[request appendData:date];
[request appendData:TID];
[request appendData:PIN];

NSString *SI = [NSString stringWithFormat:@"00%lu",(unsigned long)[request length]];
NSData *SIData = [self convertToData:SI];

NSMutableData* fullRequest = [[NSMutableData alloc] init];
[fullRequest appendData:SIData];
[fullRequest appendData:request];