or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

analytics.mdcloud-development.mdconfiguration.mdcore-services.mddevelopment-tools.mdecommerce.mdindex.mdlive-streaming.mdlogistics.mdmedia-content.mdmessaging.mdqr-codes.mduser-management.md

qr-codes.mddocs/

0

# QR Code Generation

1

2

Generate various types of QR codes and mini program codes with customizable styling and parameters. WeChat provides three different interfaces for QR code generation, each with specific use cases and limitations.

3

4

## Capabilities

5

6

### QR Code Service Interface

7

8

Main service for generating mini program codes and traditional QR codes with various customization options.

9

10

```java { .api }

11

public interface WxMaQrcodeService {

12

// Interface A - Mini Program Codes (Limited quantity)

13

File createWxaCode(String path) throws WxErrorException;

14

File createWxaCode(String path, int width) throws WxErrorException;

15

File createWxaCode(String path, String envVersion, int width, boolean autoColor,

16

WxMaCodeLineColor lineColor, boolean isHyaline) throws WxErrorException;

17

18

byte[] createWxaCodeBytes(String path, String envVersion, int width, boolean autoColor,

19

WxMaCodeLineColor lineColor, boolean isHyaline) throws WxErrorException;

20

21

// Interface B - Unlimited Mini Program Codes

22

File createWxaCodeUnlimit(String scene, String page) throws WxErrorException;

23

File createWxaCodeUnlimit(String scene, String page, String saveDir) throws WxErrorException;

24

File createWxaCodeUnlimit(String scene, String page, boolean checkPath, String envVersion,

25

int width, boolean autoColor, WxMaCodeLineColor lineColor,

26

boolean isHyaline) throws WxErrorException;

27

28

byte[] createWxaCodeUnlimitBytes(String scene, String page, boolean checkPath,

29

String envVersion, int width, boolean autoColor,

30

WxMaCodeLineColor lineColor, boolean isHyaline) throws WxErrorException;

31

32

// Interface C - Traditional QR Codes (Limited quantity)

33

File createQrcode(String path, int width) throws WxErrorException;

34

byte[] createQrcodeBytes(String path, int width) throws WxErrorException;

35

File createQrcode(String path, int width, String saveDir) throws WxErrorException;

36

}

37

```

38

39

### QR Code Styling

40

41

Customization options for QR code appearance and behavior.

42

43

```java { .api }

44

public class WxMaCodeLineColor implements Serializable {

45

private String r; // Red component (0-255)

46

private String g; // Green component (0-255)

47

private String b; // Blue component (0-255)

48

49

public WxMaCodeLineColor();

50

public WxMaCodeLineColor(String r, String g, String b);

51

52

// Getters and setters

53

public String getR();

54

public void setR(String r);

55

public String getG();

56

public void setG(String g);

57

public String getB();

58

public void setB(String b);

59

60

// Utility methods

61

public String toJson();

62

public static WxMaCodeLineColor fromJson(String json);

63

64

// Predefined colors

65

public static WxMaCodeLineColor black() { return new WxMaCodeLineColor("0", "0", "0"); }

66

public static WxMaCodeLineColor white() { return new WxMaCodeLineColor("255", "255", "255"); }

67

public static WxMaCodeLineColor red() { return new WxMaCodeLineColor("255", "0", "0"); }

68

public static WxMaCodeLineColor green() { return new WxMaCodeLineColor("0", "255", "0"); }

69

public static WxMaCodeLineColor blue() { return new WxMaCodeLineColor("0", "0", "255"); }

70

}

71

```

72

73

## Interface Differences & Use Cases

74

75

### Interface A - Mini Program Codes (createWxaCode)

76

- **Limit**: Combined with Interface C, maximum 100,000 codes total

77

- **Use Case**: Static pages, limited scenarios

78

- **Parameters**: Direct path to mini program page

79

- **Best For**: Fixed navigation, menu items, static content

80

81

### Interface B - Unlimited Codes (createWxaCodeUnlimit)

82

- **Limit**: Unlimited generation

83

- **Use Case**: Dynamic content, user-specific codes, mass generation

84

- **Parameters**: Scene parameter (custom data up to 32 characters)

85

- **Best For**: User profiles, dynamic content, personalized sharing

86

87

### Interface C - Traditional QR Codes (createQrcode)

88

- **Limit**: Combined with Interface A, maximum 100,000 codes total

89

- **Use Case**: Traditional QR code appearance

90

- **Parameters**: Direct path to mini program page

91

- **Best For**: Print materials, traditional QR code scanners

92

93

## Usage Examples

94

95

### Basic Mini Program Code Generation

96

97

#### Simple Mini Program Code (Interface A)

98

99

```java

100

try {

101

// Basic mini program code - default settings

102

File qrFile = wxService.getQrcodeService().createWxaCode("pages/index/index");

103

104

// Save to specific directory with custom width

105

File qrFile2 = wxService.getQrcodeService().createWxaCode(

106

"pages/product/detail?id=123",

107

280 // Width in pixels

108

);

109

110

logger.info("Mini program code saved to: {}", qrFile2.getAbsolutePath());

111

112

} catch (WxErrorException e) {

113

logger.error("Failed to create mini program code: {}", e.getMessage());

114

}

115

```

116

117

#### Advanced Mini Program Code with Styling

118

119

```java

120

// Custom color for QR code lines

121

WxMaCodeLineColor lineColor = new WxMaCodeLineColor("255", "0", "0"); // Red lines

122

123

try {

124

File qrFile = wxService.getQrcodeService().createWxaCode(

125

"pages/user/profile", // Page path

126

"release", // Environment: develop, trial, release

127

430, // Width in pixels (default 430)

128

false, // Auto color (false = use lineColor)

129

lineColor, // Custom line color

130

true // Transparent background

131

);

132

133

logger.info("Styled mini program code created: {}", qrFile.getAbsolutePath());

134

135

} catch (WxErrorException e) {

136

logger.error("Failed to create styled code: {}", e.getMessage());

137

}

138

```

139

140

#### Get QR Code as Byte Array

141

142

```java

143

try {

144

byte[] qrBytes = wxService.getQrcodeService().createWxaCodeBytes(

145

"pages/shop/product?id=456",

146

"release", // Environment version

147

300, // Width

148

true, // Auto color

149

null, // Line color (null when auto color = true)

150

false // Not transparent

151

);

152

153

// Save to custom location or return to client

154

Files.write(Paths.get("/custom/path/qrcode.png"), qrBytes);

155

156

// Or return as HTTP response

157

return ResponseEntity.ok()

158

.contentType(MediaType.IMAGE_PNG)

159

.body(qrBytes);

160

161

} catch (WxErrorException | IOException e) {

162

logger.error("Failed to create QR code bytes: {}", e.getMessage());

163

}

164

```

165

166

### Unlimited Mini Program Codes (Interface B)

167

168

#### User-Specific QR Codes

169

170

```java

171

// Generate unlimited codes for each user

172

String userId = "user123";

173

String scene = "u=" + userId; // Scene parameter (max 32 characters)

174

175

try {

176

File userQR = wxService.getQrcodeService().createWxaCodeUnlimit(

177

scene, // Scene data

178

"pages/user/invite" // Landing page

179

);

180

181

// The mini program can retrieve scene data using:

182

// wx.getLaunchOptionsSync().scene or wx.getEnterOptionsSync().scene

183

184

logger.info("User QR code created: {}", userQR.getAbsolutePath());

185

186

} catch (WxErrorException e) {

187

logger.error("Failed to create user QR code: {}", e.getMessage());

188

}

189

```

190

191

#### Product QR Codes with Custom Styling

192

193

```java

194

public byte[] generateProductQR(String productId, String color) {

195

String scene = "pid=" + productId;

196

197

// Parse color

198

WxMaCodeLineColor lineColor = null;

199

if ("red".equals(color)) {

200

lineColor = WxMaCodeLineColor.red();

201

} else if ("blue".equals(color)) {

202

lineColor = WxMaCodeLineColor.blue();

203

} else {

204

lineColor = WxMaCodeLineColor.black();

205

}

206

207

try {

208

return wxService.getQrcodeService().createWxaCodeUnlimitBytes(

209

scene, // Product scene data

210

"pages/product/detail", // Product detail page

211

true, // Check path validity

212

"release", // Environment

213

400, // Width

214

false, // Manual color (use lineColor)

215

lineColor, // Custom color

216

true // Transparent background

217

);

218

219

} catch (WxErrorException e) {

220

logger.error("Failed to create product QR: {}", e.getMessage());

221

return null;

222

}

223

}

224

```

225

226

#### Bulk QR Code Generation

227

228

```java

229

@Service

230

public class QRCodeBulkService {

231

232

@Async

233

public void generateBulkUserCodes(List<String> userIds) {

234

for (String userId : userIds) {

235

try {

236

String scene = "uid=" + userId;

237

238

File qrFile = wxService.getQrcodeService().createWxaCodeUnlimit(

239

scene,

240

"pages/user/profile",

241

"/qrcodes/users/" // Save directory

242

);

243

244

// Rename file to include user ID

245

File namedFile = new File(qrFile.getParent(), "user_" + userId + ".png");

246

qrFile.renameTo(namedFile);

247

248

logger.info("Generated QR for user: {}", userId);

249

250

// Small delay to avoid rate limiting

251

Thread.sleep(100);

252

253

} catch (WxErrorException | InterruptedException e) {

254

logger.error("Failed to generate QR for user {}: {}", userId, e.getMessage());

255

}

256

}

257

}

258

}

259

```

260

261

### Traditional QR Codes (Interface C)

262

263

```java

264

try {

265

// Simple traditional QR code

266

File traditionalQR = wxService.getQrcodeService().createQrcode(

267

"pages/home/index",

268

280 // Width

269

);

270

271

// As byte array

272

byte[] qrBytes = wxService.getQrcodeService().createQrcodeBytes(

273

"pages/contact/us",

274

300

275

);

276

277

logger.info("Traditional QR code created");

278

279

} catch (WxErrorException e) {

280

logger.error("Failed to create traditional QR code: {}", e.getMessage());

281

}

282

```

283

284

### Practical Examples

285

286

#### E-commerce Product QR Codes

287

288

```java

289

@RestController

290

@RequestMapping("/api/qr")

291

public class QRCodeController {

292

293

@GetMapping("/product/{productId}")

294

public ResponseEntity<byte[]> getProductQR(@PathVariable String productId,

295

@RequestParam(defaultValue = "430") int width,

296

@RequestParam(defaultValue = "false") boolean transparent) {

297

try {

298

String scene = "pid=" + productId + "&src=qr";

299

300

byte[] qrBytes = wxService.getQrcodeService().createWxaCodeUnlimitBytes(

301

scene,

302

"pages/product/detail",

303

true, // Check path

304

"release", // Environment

305

width,

306

true, // Auto color

307

null,

308

transparent

309

);

310

311

return ResponseEntity.ok()

312

.contentType(MediaType.IMAGE_PNG)

313

.header("Cache-Control", "public, max-age=86400") // Cache 1 day

314

.body(qrBytes);

315

316

} catch (WxErrorException e) {

317

logger.error("Failed to generate product QR: {}", e.getMessage());

318

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

319

}

320

}

321

}

322

```

323

324

#### User Invitation System

325

326

```java

327

@Service

328

public class InvitationService {

329

330

public String generateInviteQR(String inviterId, String campaignId) {

331

String scene = String.format("inv=%s&cmp=%s", inviterId, campaignId);

332

333

// Validate scene length (max 32 characters)

334

if (scene.length() > 32) {

335

// Use shorter encoding or hash

336

scene = "inv=" + hashCode(inviterId + campaignId);

337

}

338

339

try {

340

File qrFile = wxService.getQrcodeService().createWxaCodeUnlimit(

341

scene,

342

"pages/invite/landing",

343

"/tmp/invites/"

344

);

345

346

// Upload to CDN or cloud storage

347

String qrUrl = uploadToCDN(qrFile);

348

349

// Store mapping for analytics

350

inviteRepository.save(new Invite(inviterId, campaignId, scene, qrUrl));

351

352

return qrUrl;

353

354

} catch (WxErrorException e) {

355

logger.error("Failed to generate invite QR: {}", e.getMessage());

356

throw new QRGenerationException("Could not generate invitation QR code");

357

}

358

}

359

360

private String hashCode(String input) {

361

// Simple hash for scene parameter

362

return Integer.toHexString(input.hashCode()).substring(0, 8);

363

}

364

}

365

```

366

367

#### Event Check-in QR Codes

368

369

```java

370

@Component

371

public class EventQRGenerator {

372

373

public Map<String, Object> generateEventQRs(String eventId, List<String> sessions) {

374

Map<String, Object> result = new HashMap<>();

375

List<String> qrUrls = new ArrayList<>();

376

377

for (String sessionId : sessions) {

378

try {

379

String scene = "evt=" + eventId + "&ses=" + sessionId;

380

381

// Custom styling for events

382

WxMaCodeLineColor eventColor = new WxMaCodeLineColor("0", "123", "255"); // Blue

383

384

byte[] qrBytes = wxService.getQrcodeService().createWxaCodeUnlimitBytes(

385

scene,

386

"pages/event/checkin",

387

true, // Check path

388

"release",

389

350, // Larger size for scanning

390

false, // Custom color

391

eventColor, // Event brand color

392

false // Solid background

393

);

394

395

// Save with descriptive name

396

String filename = String.format("event_%s_session_%s.png", eventId, sessionId);

397

String qrPath = saveQRCode(qrBytes, filename);

398

qrUrls.add(qrPath);

399

400

} catch (WxErrorException e) {

401

logger.error("Failed to generate QR for event {} session {}: {}",

402

eventId, sessionId, e.getMessage());

403

}

404

}

405

406

result.put("eventId", eventId);

407

result.put("qrCodes", qrUrls);

408

result.put("count", qrUrls.size());

409

410

return result;

411

}

412

}

413

```

414

415

### Error Handling

416

417

```java

418

public class QRCodeService {

419

420

public byte[] generateQRWithFallback(String scene, String page) {

421

try {

422

// Try unlimited interface first (preferred)

423

return wxService.getQrcodeService().createWxaCodeUnlimitBytes(

424

scene, page, true, "release", 430, true, null, false

425

);

426

427

} catch (WxErrorException e) {

428

int errorCode = e.getError().getErrorCode();

429

430

switch (errorCode) {

431

case 45009:

432

logger.warn("API quota exceeded for unlimited codes");

433

// Fall back to limited interface

434

return generateLimitedQR(page);

435

436

case 41030:

437

logger.error("Invalid scene parameter: {}", scene);

438

throw new IllegalArgumentException("Invalid scene parameter");

439

440

case 45006:

441

logger.error("Invalid page path: {}", page);

442

throw new IllegalArgumentException("Invalid page path");

443

444

default:

445

logger.error("QR generation failed: {} - {}",

446

errorCode, e.getError().getErrorMsg());

447

throw new QRGenerationException("Failed to generate QR code", e);

448

}

449

}

450

}

451

452

private byte[] generateLimitedQR(String page) {

453

try {

454

return wxService.getQrcodeService().createWxaCodeBytes(

455

page, "release", 430, true, null, false

456

);

457

} catch (WxErrorException e) {

458

logger.error("Fallback QR generation also failed: {}", e.getMessage());

459

throw new QRGenerationException("All QR generation methods failed", e);

460

}

461

}

462

}

463

```

464

465

### Performance Optimization

466

467

```java

468

@Service

469

public class OptimizedQRService {

470

471

private final RedisTemplate<String, byte[]> redisTemplate;

472

private final ExecutorService qrExecutor = Executors.newFixedThreadPool(5);

473

474

@Cacheable(value = "qrcodes", key = "#scene + '_' + #page + '_' + #width")

475

public byte[] getCachedQR(String scene, String page, int width) {

476

try {

477

return wxService.getQrcodeService().createWxaCodeUnlimitBytes(

478

scene, page, true, "release", width, true, null, false

479

);

480

} catch (WxErrorException e) {

481

logger.error("QR generation failed: {}", e.getMessage());

482

return null;

483

}

484

}

485

486

@Async

487

public CompletableFuture<String> generateQRAsync(String scene, String page) {

488

return CompletableFuture.supplyAsync(() -> {

489

try {

490

File qrFile = wxService.getQrcodeService().createWxaCodeUnlimit(scene, page);

491

return uploadToStorage(qrFile);

492

} catch (WxErrorException e) {

493

logger.error("Async QR generation failed: {}", e.getMessage());

494

return null;

495

}

496

}, qrExecutor);

497

}

498

}

499

```

500

501

This QR code service provides comprehensive code generation capabilities with proper error handling, caching strategies, and support for all WeChat QR code interfaces.