C语言在魔方财务系统中集成零零七云计算短信服务详解
目录
简介
本文档详细介绍了如何使用C语言在魔方财务系统中集成零零七云计算(007IDC)提供的短信服务。通过系统调用,实现国内/国际短信通知、短信验证、用户请求验证等功能。文档涵盖了插件对接的前提条件、安装配置步骤、API接口的详细说明及C语言代码示例,帮助开发者高效地完成短信服务的集成。
前提条件
在开始集成之前,请确保满足以下条件:
- 购买短信资源包:在启用该应用之前,请确保已在零零七云计算(007IDC)购买了短信资源包。
- 获取账号信息:
- 短信服务地址:访问零零七云计算(007IDC)的短信服务购买页面(新用户注册点击注册)。
- 平台账号密码:获取零零七云计算(007IDC)平台的账号和密码。
- 短信额度:大量短信额度价格可商量,不能过低。如有问题,请联系客服经理:1485174354。
安装与配置
购买并配置短信插件
购买插件:
- 购买插件后,登录魔方财务后台。
- 导航至 系统 > 短信邮件设置 > 接口设置 > 短信设置 管理页面。
- 找到 零零七云计算·云通信,点击右侧 安装 按钮进行安装。
配置插件:
- 安装完成后,点击右侧 配置 按钮。
- 填写相关配置信息,包括
appkey
、appCode
、appSecret
等。 - 保存配置。
配置短信模板:
- 打开 短信模板 页面,将供应商切换为 零零七短信平台。
- 勾选需要使用的短信模板并提交审核。
发送设置:
- 审核通过后,点击 发送设置 页面,将供应商切换为 零零七短信平台。
- 保存设置后,点击 测试发送 以验证配置是否成功。
手动安装(如自动安装失败)
- 点击应用商店上方的 我的 按钮,找到该插件。
- 点击 安装 或 下载 按钮,进行立即安装或重新下载。
API接口对接
零零七云计算提供多种API接口,用于发送短信、接收状态报告、查询余额等。以下详细介绍各个API接口的使用方法及C语言实现方式。
1. 一对多群发短信
接口地址:http://sms.007idc.cn:9090/sms/batch/v1
请求方式:POST
请求头:
Content-Type: application/json
请求参数:
参数名称 | 参数说明 | 备注 |
---|---|---|
appkey | 应用key-登录账号 | *必填,由供应商提供 |
appcode | 应用代码-默认1000 | *必填,由供应商提供,默认为1000 |
sign | 短信签名验证MD5(appkey+appsecret+timestamp) | *必填,秘钥 appsecret 由供应商提供,由 appkey + appsecret + timestamp 经过 MD5 加密后的32位16进制小写字符串(拼接过程不包括 + ) |
phone | 手机号码 | *必填,多个号码用半角英文逗号隔开,一次最多不能超过1000个 |
msg | 下发短信内容 | *必填,短信内容长度不超过1000个字(包括1000字),每个英文或阿拉伯字符算1个字 |
timestamp | 时间戳 | *必填,时间戳(精确到毫秒),当前时间5分钟内请求有效 |
extend | 扩展号 | 选填,可为空数字,如:001,119等,通道本身主叫号加上用户自己分配扩展号的总长度不能超过20位 |
请求示例:
{
"sign": "de7cb2fb99756c06214fc78252d36484",
"timestamp": "1520496753938",
"phone": "15100000055,15100000044",
"extend": "123",
"appcode": "test",
"appkey": "test",
"msg": "你好,测试"
}
响应信息说明:
- 请求成功:
{
"code": "00000",
"desc": "提交成功",
"uid": "8b159b0036d0402e93b39fee102eedf2",
"result": [
{
"status": "00000",
"phone": "15100000055",
"desc": "提交成功"
},
{
"status": "00000",
"phone": "15100000044",
"desc": "提交成功"
}
]
}
- 请求异常:
{
"code": "F0006",
"desc": "appkey不存在",
"uid": "6e31047a352346f18a0eb2daadb9f217",
"result": []
}
2. 一对一内容群发
接口地址:http://sms.007idc.cn:9090/sms/distinct/v1
请求方式:POST
请求头:
Content-Type: application/json
请求参数:
参数名称 | 参数说明 | 备注 |
---|---|---|
appkey | 应用key-登录账号 | *必填,由供应商提供 |
appcode | 应用代码-默认1000 | *必填,由供应商提供,默认为1000 |
sign | 短信签名验证MD5(appkey+appsecret+timestamp) | *必填,秘钥 appsecret 由供应商提供,由 appkey + appsecret + timestamp 经过 MD5 加密后的32位16进制小写字符串(拼接过程不包括 + ) |
sms | 个性化信息sms[] | *必填,个性化信息,短信条数不能超过1000条 |
timestamp | 时间戳 | *必填,时间戳(精确到毫秒),当前时间5分钟内请求有效 |
number | 数量 | 选填,可为空数字,范围1到1000,不在该范围采用默认值200 |
sms结构:
字段 | 类型 | 说明 |
---|---|---|
phone | String | *必填,手机号码 |
msg | String | *必填,短信内容长度不超过1000个字(包括1000字),每个英文或阿拉伯字符算1个字 |
extend | String | 选填,可为空数字,如:001,119等,通道本身主叫号加上用户自己分配扩展号的总长度不能超过20位 |
请求示例:
{
"appkey": "test",
"appcode": "test",
"sign": "de7cb2fb99756c06214fc78252d36484",
"timestamp": "1520496753938",
"sms": [
{
"msg": "短信内容1",
"phone": "15100000055",
"extend": ""
},
{
"msg": "短信内容2",
"phone": "15100000044",
"extend": "11"
}
]
}
响应信息说明:
- 请求成功:
{
"code": "00000",
"desc": "提交成功",
"result": [
{
"status": "00000",
"phone": "15100000055",
"desc": "提交成功",
"uid": "8b159b0036d0402e93b39fee102eedf2"
},
{
"status": "00000",
"phone": "15100000044",
"desc": "提交成功",
"uid": "8b159b0036d0402e93b39fee102ee587"
}
]
}
- 请求异常:
{
"code": "F0006",
"desc": "appkey不存在",
"uid": "6e31047a352346f18a0eb2daadb9f217",
"result": []
}
3. 状态报告平台推送
推送地址:由接收方提供,平台绑定后推送该地址。
推送格式:
[
{
"appkey": "huoguo",
"desc": "DELIVRD",
"phone": "15200000006",
"report_time": "2018-03-15 01:01:46",
"status": "0",
"uid": "143536bbc41e4ef69c779cbb125f7317"
},
{
"appkey": "huoguo",
"desc": "UNDELIV",
"phone": "15200000007",
"report_time": "2018-03-15 01:01:49",
"status": "2",
"uid": "b671244d5c534cf7a10f3b99c31aa086"
}
]
字段说明:
字段 | 类型 | 说明 |
---|---|---|
appkey | String | 应用key |
phone | String | 手机号码 |
status | String | 状态 0-成功 其他失败 |
desc | String | 状态码描述 |
uid | String | 短信唯一标识,对应提交响应返回的uid |
report_time | String | 状态报告时间 |
推送规则:
存在多条状态报告时,一次最多推送100条。
接收成功需要返回:
{"code": "00000"}
返回其他值视为接收异常,会尝试最多推送三次。
4. 状态报告用户自取
接口地址:http://sms.007idc.cn:9090/sms/report/v1
请求方式:GET
请求参数:
参数名称 | 参数说明 | 备注 |
---|---|---|
appkey | 应用key-登录账号 | *必填,由供应商提供 |
appcode | 应用代码-默认1000 | *必填,由供应商提供,默认为1000 |
sign | 短信签名验证MD5(appkey+appsecret+timestamp) | *必填,秘钥 appsecret 由供应商提供,由 appkey + appsecret + timestamp 经过 MD5 加密后的32位16进制小写字符串(拼接过程不包括 + ) |
timestamp | 时间戳 | *必填,时间戳(精确到毫秒),当前时间5分钟内请求有效 |
number | 数量 | 选填,可为空,数字,范围1到1000,不在该范围采用默认值200 |
请求示例:
// URL示例
http://sms.007idc.cn:9090/sms/report/v1?appkey=test&appcode=1000&sign=de7cb2fb99756c06214fc78252d36484×tamp=1520496753938&number=100
响应信息说明:
- 请求成功:
[
{
"appkey": "huoguo",
"desc": "DELIVRD",
"phone": "15200000006",
"report_time": "2018-03-15 01:01:46",
"status": "0",
"uid": "143536bbc41e4ef69c779cbb125f7317"
},
{
"appkey": "huoguo",
"desc": "UNDELIV",
"phone": "15200000007",
"report_time": "2018-03-15 01:01:49",
"status": "2",
"uid": "b671244d5c534cf7a10f3b99c31aa086"
}
]
- 无数据:
{
"code": "F0050",
"desc": "无数据"
}
- 请求异常:
{
"code": "F0006",
"desc": "appkey不存在"
}
5. 上行平台推送
推送地址:由接收方提供,平台绑定后推送该地址。
推送格式:
[
{
"appkey": "huoguo",
"deliver_time": "2018-03-15 01:35:41",
"extend": "123",
"msg": "TD",
"phone": "13900000200"
},
{
"appkey": "huoguo",
"deliver_time": "2018-03-15 01:35:41",
"extend": "",
"msg": "TD",
"phone": "13900000200"
}
]
字段说明:
字段 | 类型 | 说明 |
---|---|---|
appkey | String | 应用key |
phone | String | 手机号码 |
msg | String | 上行回复内容 |
extend | String | 扩展号,对应发送填写的extend |
deliver_time | String | 上行回复时间 |
推送规则:
存在多条上行时,一次最多推送10条。
接收成功需要返回:
{"code": "00000"}
返回其他值视为接收异常,会尝试最多推送三次。
6. 上行用户自取
接口地址:http://sms.007idc.cn:9090/sms/mo/v1
请求方式:GET
请求参数:
参数名称 | 参数说明 | 备注 |
---|---|---|
appkey | 应用key-登录账号 | *必填,由供应商提供 |
appcode | 应用代码-默认1000 | *必填,由供应商提供,默认为1000 |
sign | 短信签名验证MD5(appkey+appsecret+timestamp) | *必填,秘钥 appsecret 由供应商提供,由 appkey + appsecret + timestamp 经过 MD5 加密后的32位16进制小写字符串(拼接过程不包括 + ) |
timestamp | 时间戳 | *必填,时间戳(精确到毫秒),当前时间5分钟内请求有效 |
number | 数量 | 选填,可为空,数字,范围1到1000,不在该范围采用默认值200 |
请求示例:
// URL示例
http://sms.007idc.cn:9090/sms/mo/v1?appkey=test&appcode=1000&sign=de7cb2fb99756c06214fc78252d36484×tamp=1520496753938&number=100
响应信息说明:
- 请求成功:
[
{
"appkey": "huoguo",
"deliver_time": "2018-03-15 01:35:41",
"extend": "123",
"msg": "TD",
"phone": "13900000200"
},
{
"appkey": "huoguo",
"deliver_time": "2018-03-15 01:35:41",
"extend": "",
"msg": "TD",
"phone": "13900000200"
}
]
- 无数据:
{
"code": "F0050",
"desc": "无数据"
}
- 请求异常:
{
"code": "F0006",
"desc": "appkey不存在"
}
7. 查询余额
接口地址:http://sms.007idc.cn:9090/sms/balance/v1
请求方式:GET
请求参数:
参数名称 | 参数说明 | 备注 |
---|---|---|
appkey | 应用key-登录账号 | *必填,由供应商提供 |
appcode | 应用代码-默认1000 | *必填,由供应商提供,默认为1000 |
sign | 短信签名验证MD5(appkey+appsecret+timestamp) | *必填,秘钥 appsecret 由供应商提供,由 appkey + appsecret + timestamp 经过 MD5 加密后的32位16进制小写字符串(拼接过程不包括 + ) |
timestamp | 时间戳 | *必填,时间戳(精确到毫秒),当前时间5分钟内请求有效 |
请求示例:
// URL示例
http://sms.007idc.cn:9090/sms/balance/v1?appkey=test&appcode=1000&sign=de7cb2fb99756c06214fc78252d36484×tamp=1520496753938
响应信息说明:
- 请求成功:
{
"appkey": "test",
"balance": "50",
"balance_time": "2018-03-15 01:01:46"
}
- 请求异常:
{
"code": "F0006",
"desc": "appkey不存在"
}
错误处理
所有API接口在请求失败时,会返回相应的错误码和描述。以下是常见错误码说明:
返回代码 | 错误码描述 |
---|---|
00000 |
提交成功 |
F0001 |
参数 appkey 未填写 |
F0002 |
参数 appcode 未填写 |
F0003 |
参数 phone 未填写 |
F0004 |
参数 sign 未填写 |
F0005 |
参数 timestamp 未填写 |
F0006 |
appkey 不存在 |
F0007 |
账号已经关闭 |
F0008 |
sign 检验错误 |
F0009 |
账号下没有业务 |
F0010 |
业务不存在 |
F0011 |
手机号码超过1000个 |
F0012 |
timestamp 不是数字 |
F0013 |
timestamp 过期超过5分钟 |
F0014 |
请求IP不在白名单内 |
F0015 |
余额不足 |
F0016 |
手机号码无效 |
F0017 |
没有可用的业务 |
F0022 |
参数 msg 未填写 |
F0023 |
msg 超过了1000个字 |
F0024 |
extend 不是纯数字 |
F0025 |
内容签名未报备/无签名 |
F0039 |
参数 sms 未填写 |
F0040 |
参数 sms 格式不正确 |
F0041 |
短信条数超过1000条 |
F0050 |
无数据 |
F0100 |
未知错误 |
错误处理示例:
在C语言中,处理API返回的错误码需要解析JSON响应,并根据 code
字段进行相应的处理。
实用C语言代码示例
以下示例使用C语言和libcurl库进行HTTP请求,使用cJSON库解析JSON数据,并通过OpenSSL库计算MD5签名。请确保在编译时链接相应的库(如 -lcurl -lcjson -lssl -lcrypto
)。
前置准备
安装必要库:
sudo apt-get update sudo apt-get install libcurl4-openssl-dev libssl-dev sudo apt-get install libcjson-dev
包含头文件:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <curl/curl.h> #include <cjson/cJSON.h> #include <openssl/md5.h> #include <time.h>
1. 一对多群发短信示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <cjson/cJSON.h>
#include <openssl/md5.h>
#include <time.h>
// Function to compute MD5 hash
void compute_md5(const char *str, char *output) {
unsigned char digest[MD5_DIGEST_LENGTH];
MD5((unsigned char*)str, strlen(str), digest);
for(int i = 0; i < MD5_DIGEST_LENGTH; i++) {
sprintf(&output[i*2], "%02x", (unsigned int)digest[i]);
}
output[32] = '\0';
}
// Function to get current timestamp in milliseconds
long long current_timestamp_ms() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return (long long)(ts.tv_sec) * 1000 + ts.tv_nsec / 1000000;
}
// Callback function to handle response data
size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
size_t realsize = size * nmemb;
char **response_ptr = (char**)userp;
*response_ptr = realloc(*response_ptr, realsize + 1);
if(*response_ptr == NULL) {
fprintf(stderr, "Not enough memory (realloc returned NULL)\n");
return 0;
}
memcpy(*response_ptr, contents, realsize);
(*response_ptr)[realsize] = '\0';
return realsize;
}
int main() {
CURL *curl;
CURLcode res;
char *response = NULL;
// Configuration
const char *appkey = "your_appkey";
const char *appsecret = "your_appsecret";
const char *appcode = "1000";
const char *sign_format = "%s%s%lld";
long long timestamp = current_timestamp_ms();
// Compute sign
char sign_input[256];
snprintf(sign_input, sizeof(sign_input), sign_format, appkey, appsecret, timestamp);
char sign[33];
compute_md5(sign_input, sign);
// Prepare JSON payload
cJSON *json = cJSON_CreateObject();
cJSON_AddStringToObject(json, "appkey", appkey);
cJSON_AddStringToObject(json, "appcode", appcode);
cJSON_AddStringToObject(json, "sign", sign);
cJSON_AddStringToObject(json, "phone", "15100000055,15100000044");
cJSON_AddStringToObject(json, "msg", "【零零七】 您的验证码是124154");
cJSON_AddStringToObject(json, "timestamp", "1520496753938"); // Replace with actual timestamp
char *json_data = cJSON_PrintUnformatted(json);
cJSON_Delete(json);
// Initialize CURL
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, "http://sms.007idc.cn:9090/sms/batch/v1");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// Set callback to capture response
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
// Perform the request
res = curl_easy_perform(curl);
// Check for errors
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
} else {
// Parse JSON response
cJSON *json_response = cJSON_Parse(response);
if(json_response == NULL) {
fprintf(stderr, "Error parsing JSON response\n");
} else {
cJSON *code = cJSON_GetObjectItem(json_response, "code");
if(cJSON_IsString(code) && (code->valuestring != NULL)) {
printf("Response Code: %s\n", code->valuestring);
if(strcmp(code->valuestring, "00000") == 0) {
printf("短信发送成功\n");
} else {
// Handle error based on code
printf("短信发送失败,错误码: %s\n", code->valuestring);
}
}
cJSON_Delete(json_response);
}
}
// Cleanup
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
free(json_data);
free(response);
return 0;
}
说明:
- 计算MD5签名:使用OpenSSL库的
MD5
函数计算签名。 - 获取当前时间戳:使用
clock_gettime
获取当前时间的毫秒级时间戳。 - 构建JSON请求体:使用cJSON库构建JSON格式的请求体。
- 发送HTTP POST请求:使用libcurl发送HTTP POST请求,并设置相应的头部信息。
- 处理响应:接收并解析JSON格式的响应,检查返回码
code
,判断短信是否发送成功。
2. 一对一内容群发短信示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <cjson/cJSON.h>
#include <openssl/md5.h>
#include <time.h>
// Function to compute MD5 hash
void compute_md5(const char *str, char *output) {
unsigned char digest[MD5_DIGEST_LENGTH];
MD5((unsigned char*)str, strlen(str), digest);
for(int i = 0; i < MD5_DIGEST_LENGTH; i++) {
sprintf(&output[i*2], "%02x", (unsigned int)digest[i]);
}
output[32] = '\0';
}
// Function to get current timestamp in milliseconds
long long current_timestamp_ms() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return (long long)(ts.tv_sec) * 1000 + ts.tv_nsec / 1000000;
}
// Callback function to handle response data
size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
size_t realsize = size * nmemb;
char **response_ptr = (char**)userp;
*response_ptr = realloc(*response_ptr, realsize + 1);
if(*response_ptr == NULL) {
fprintf(stderr, "Not enough memory (realloc returned NULL)\n");
return 0;
}
memcpy(*response_ptr, contents, realsize);
(*response_ptr)[realsize] = '\0';
return realsize;
}
int main() {
CURL *curl;
CURLcode res;
char *response = NULL;
// Configuration
const char *appkey = "your_appkey";
const char *appsecret = "your_appsecret";
const char *appcode = "1000";
const char *sign_format = "%s%s%lld";
long long timestamp = current_timestamp_ms();
// Compute sign
char sign_input[256];
snprintf(sign_input, sizeof(sign_input), sign_format, appkey, appsecret, timestamp);
char sign[33];
compute_md5(sign_input, sign);
// Prepare JSON payload
cJSON *json = cJSON_CreateObject();
cJSON_AddStringToObject(json, "appkey", appkey);
cJSON_AddStringToObject(json, "appcode", appcode);
cJSON_AddStringToObject(json, "sign", sign);
cJSON_AddStringToObject(json, "timestamp", "1520496753938"); // Replace with actual timestamp
// Create sms array
cJSON *sms_array = cJSON_AddArrayToObject(json, "sms");
// Add individual SMS messages
cJSON *sms1 = cJSON_CreateObject();
cJSON_AddStringToObject(sms1, "msg", "【测试】你好测试0");
cJSON_AddStringToObject(sms1, "phone", "15100000410");
cJSON_AddStringToObject(sms1, "extend", "0010");
cJSON_AddItemToArray(sms_array, sms1);
cJSON *sms2 = cJSON_CreateObject();
cJSON_AddStringToObject(sms2, "msg", "【测试】你好测试1");
cJSON_AddStringToObject(sms2, "phone", "15100000411");
cJSON_AddStringToObject(sms2, "extend", "0011");
cJSON_AddItemToArray(sms_array, sms2);
char *json_data = cJSON_PrintUnformatted(json);
cJSON_Delete(json);
// Initialize CURL
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, "http://sms.007idc.cn:9090/sms/distinct/v1");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// Set callback to capture response
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
// Perform the request
res = curl_easy_perform(curl);
// Check for errors
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
} else {
// Parse JSON response
cJSON *json_response = cJSON_Parse(response);
if(json_response == NULL) {
fprintf(stderr, "Error parsing JSON response\n");
} else {
cJSON *code = cJSON_GetObjectItem(json_response, "code");
if(cJSON_IsString(code) && (code->valuestring != NULL)) {
printf("Response Code: %s\n", code->valuestring);
if(strcmp(code->valuestring, "00000") == 0) {
printf("短信发送成功\n");
} else {
// Handle error based on code
printf("短信发送失败,错误码: %s\n", code->valuestring);
}
}
cJSON_Delete(json_response);
}
}
// Cleanup
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
free(json_data);
free(response);
return 0;
}
说明:
- 构建SMS数组:通过cJSON库创建一个包含多个SMS消息的数组,每个消息包含
msg
、phone
和extend
字段。 - 发送请求:与一对多群发类似,使用libcurl发送HTTP POST请求,设置相应的头部信息和JSON数据。
- 处理响应:解析JSON响应,检查返回码
code
,判断短信是否发送成功。
3. 查询余额示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <cjson/cJSON.h>
#include <openssl/md5.h>
#include <time.h>
// Function to compute MD5 hash
void compute_md5(const char *str, char *output) {
unsigned char digest[MD5_DIGEST_LENGTH];
MD5((unsigned char*)str, strlen(str), digest);
for(int i = 0; i < MD5_DIGEST_LENGTH; i++) {
sprintf(&output[i*2], "%02x", (unsigned int)digest[i]);
}
output[32] = '\0';
}
// Function to get current timestamp in milliseconds
long long current_timestamp_ms() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return (long long)(ts.tv_sec) * 1000 + ts.tv_nsec / 1000000;
}
// Callback function to handle response data
size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
size_t realsize = size * nmemb;
char **response_ptr = (char**)userp;
*response_ptr = realloc(*response_ptr, realsize + 1);
if(*response_ptr == NULL) {
fprintf(stderr, "Not enough memory (realloc returned NULL)\n");
return 0;
}
memcpy(*response_ptr, contents, realsize);
(*response_ptr)[realsize] = '\0';
return realsize;
}
int main() {
CURL *curl;
CURLcode res;
char *response = NULL;
// Configuration
const char *appkey = "your_appkey";
const char *appsecret = "your_appsecret";
const char *appcode = "1000";
const char *sign_format = "%s%s%lld";
long long timestamp = current_timestamp_ms();
// Compute sign
char sign_input[256];
snprintf(sign_input, sizeof(sign_input), sign_format, appkey, appsecret, timestamp);
char sign[33];
compute_md5(sign_input, sign);
// Prepare URL with query parameters
char url[512];
snprintf(url, sizeof(url), "http://sms.007idc.cn:9090/sms/balance/v1?appkey=%s&appcode=%s&sign=%s×tamp=%lld",
appkey, appcode, sign, timestamp);
// Initialize CURL
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
// Set URL
curl_easy_setopt(curl, CURLOPT_URL, url);
// Set callback to capture response
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
// Perform the request
res = curl_easy_perform(curl);
// Check for errors
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
} else {
// Parse JSON response
cJSON *json_response = cJSON_Parse(response);
if(json_response == NULL) {
fprintf(stderr, "Error parsing JSON response\n");
} else {
cJSON *balance = cJSON_GetObjectItem(json_response, "balance");
cJSON *balance_time = cJSON_GetObjectItem(json_response, "balance_time");
if(cJSON_IsString(balance) && (balance->valuestring != NULL) &&
cJSON_IsString(balance_time) && (balance_time->valuestring != NULL)) {
printf("账户余额: %s 条\n", balance->valuestring);
printf("余额更新时间: %s\n", balance_time->valuestring);
} else {
cJSON *code = cJSON_GetObjectItem(json_response, "code");
cJSON *desc = cJSON_GetObjectItem(json_response, "desc");
if(cJSON_IsString(code) && (code->valuestring != NULL) &&
cJSON_IsString(desc) && (desc->valuestring != NULL)) {
printf("查询失败,错误码: %s, 描述: %s\n", code->valuestring, desc->valuestring);
} else {
printf("未知响应格式\n");
}
}
cJSON_Delete(json_response);
}
}
// Cleanup
curl_easy_cleanup(curl);
}
curl_global_cleanup();
free(response);
return 0;
}
说明:
- 构建URL:将必要的参数(
appkey
、appcode
、sign
、timestamp
)作为查询参数附加到URL中。 - 发送GET请求:使用libcurl发送HTTP GET请求。
- 处理响应:解析JSON响应,提取余额信息或错误信息。
编译与运行
使用以下命令编译上述示例代码:
gcc -o send_sms_batch send_sms_batch.c -lcurl -lcjson -lssl -lcrypto
gcc -o send_sms_distinct send_sms_distinct.c -lcurl -lcjson -lssl -lcrypto
gcc -o query_balance query_balance.c -lcurl -lcjson -lssl -lcrypto
然后运行相应的可执行文件:
./send_sms_batch
./send_sms_distinct
./query_balance
附录:常见错误码说明
以下是零零七云计算短信服务的常见错误码及其描述:
返回代码 | 错误码描述 |
---|---|
00000 |
提交成功 |
F0001 |
参数 appkey 未填写 |
F0002 |
参数 appcode 未填写 |
F0003 |
参数 phone 未填写 |
F0004 |
参数 sign 未填写 |
F0005 |
参数 timestamp 未填写 |
F0006 |
appkey 不存在 |
F0007 |
账号已经关闭 |
F0008 |
sign 检验错误 |
F0009 |
账号下没有业务 |
F0010 |
业务不存在 |
F0011 |
手机号码超过1000个 |
F0012 |
timestamp 不是数字 |
F0013 |
timestamp 过期超过5分钟 |
F0014 |
请求IP不在白名单内 |
F0015 |
余额不足 |
F0016 |
手机号码无效 |
F0017 |
没有可用的业务 |
F0022 |
参数 msg 未填写 |
F0023 |
msg 超过了1000个字 |
F0024 |
extend 不是纯数字 |
F0025 |
内容签名未报备/无签名 |
F0039 |
参数 sms 未填写 |
F0040 |
参数 sms 格式不正确 |
F0041 |
短信条数超过1000条 |
F0050 |
无数据 |
F0100 |
未知错误 |
处理建议:
- 成功:代码
00000
表示短信提交成功。 - 失败:其他代码表示不同类型的错误,应根据错误码描述进行相应的处理,如重新发送、提示用户错误信息等。
总结
本文档详细介绍了如何使用C语言在魔方财务系统中集成零零七云计算(007IDC)的短信服务。通过系统调用实现国内/国际短信通知、短信验证、用户请求验证等功能。文档涵盖了插件对接的前提条件、安装配置步骤、API接口的详细说明及C语言代码示例,帮助开发者高效地完成短信服务的集成。
关键点:
- 安全性:确保
appkey
和appsecret
的安全,避免泄露。 - 时间戳:所有请求均需包含精确到毫秒的时间戳,且必须在当前时间5分钟内。
- 签名计算:签名为
appkey
+appsecret
+timestamp
的MD5值,需为32位16进制小写字符串。 - 错误处理:根据返回的错误码进行相应的处理,确保程序的健壮性。
- 库依赖:使用libcurl进行HTTP请求,cJSON进行JSON处理,OpenSSL进行MD5签名计算。
建议:
- 测试:在正式使用前,建议通过提供的测试发送功能进行充分测试,确保接口对接正确。
- 文档参考:详细阅读零零七云计算提供的官方文档,了解最新的接口变更和使用规范。
- 日志记录:在实际应用中,建议记录发送日志和响应信息,便于后续的排查和维护。
通过本文档的指导,您将能够在C语言环境下高效地集成零零七云计算的短信服务,满足魔方财务系统的短信通知和验证需求。